In class yesterday I mentioned how important it is for you - or, better, someone you trust - to test your code. This is the first of a three-part series of messages about a simple way to test your code. Let me know if you have any questions or comments. I mostly use the JUnit testing framework ( junit.org ) to test my Java code, but I also use a simpler testing scheme that uses nothing but java. I'm going to describe the simpler scheme here. Let's suppose you've written a linked-list class: $ cat LinkedList.java public class LinkedList<E> implements LinkedSequence<E> { // blah blah blah } $ Now you want to test your class. The testing scheme adds a main method to the class you want to test (LinkedList in this case) and puts the testing code in main. Once you've done that, you can test your class by running it. Q: But what if the class C I want to test already has a main() method? A: There's a couple of ways to handle classes with existing main() methods. The first, and probably the best, way is to refactor your class so the main() method is in its own class. Now class C has no main, and you can add your testing main. If, for whatever reason, you can't factor out main, you have to do something uglier: change main() to recognize a command-line argument, "-t" say. When main() finds the command-line argument, it runs the testing code instead of doing what ever it usually does. For example, suppose the linked-list class doesn't have a main() method; add one: $ cat LinkedList.java public class LinkedList<E> implements LinkedSequence<E> { // blah blah blah public static void main(String args[]) { } // blah blah blah } $ In this case main() doesn't do anything; we'll consider what to put in main() in part 2. Once a class has a main and compiles successfully, you can run the class; that is, call its main method(): $ javac -classpath pa1.jar:. LinkedList $ java -classpath pa1.jar:. LinkedList Now suppose that the linked-list class already has a main that can't be refactored into a separate class: $ cat LinkedList.java public class LinkedList<E> implements LinkedSequence<E> { // blah blah blah public static void main(String args[]) { System.out.println("Do important stuff."); } // blah blah blah } $ Change main() to look through the command-line arguments for the testing option, and run the tests if it finds it: $ cat LinkedList.java public class LinkedList<E> implements LinkedSequence<E> { // blah blah blah public static void main(String args[]) { if ((args.length > 0) && args[0].equals("-t")) System.out.println("Do testing."); else System.out.println("Do important stuff."); } // blah blah blah } $ This example assumes the non-testing main() doesn't use any command-line arguments. If it does, the search for the testing option will be more complicated, but it can probably be folded in with the other command-line processing. $ javac -classpath pa1.jar:. LinkedList.java $ java -classpath pa1.jar:. LinkedList Do important stuff. $ java -classpath pa1.jar:. LinkedList -t Do testing. $ That's it for the simple testing framework; you can add it to each class you want to test (which should be every class you write). Q: Really? There won't be any trouble with having multiple main() methods? A: No. Unlike other, more conventional languages you may know, java doesn't require that there only be one main() defined. Instead, you tell the JVM which class's main() method you want it to run, and execution proceeds from there. (And if that class doesn't define a main() method, you'll get the usual Exception in thread "main" java.lang.NoSuchMethodError: main explosion.)Received on Fri Feb 19 2010 - 10:30:17 EST
This archive was generated by hypermail 2.2.0 : Fri Feb 19 2010 - 20:02:55 EST