CS 580 Client-Server Programming Fall Semester, 2000 Testing |
||
---|---|---|
© 2000, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 30-Aug-00 |
Testing
Johnson's Law
If it is not tested it does not work
Types of tests
Why Unit Testing
If it is not tested it does not work
The more time between coding and testing
When to Write Unit Tests
First write the tests
Then write the code to be tested
Writing tests first saves time
JUnit
Framework for unit testing Java code
Available at: http://www.junit.org/
Already installed in JDK 1.2 on rohan and moria
Ports of JUnit are available in
C++ |
Delphi |
Eiffel |
Forte
4GL
|
Objective-C |
Perl |
PowerBuilder |
Python |
Ruby |
Smalltalk |
Visual
Basic
|
|
Using JUnit
Example
Goal: Implement a Stack containing integers.
Tests:
package example; import junit.framework.TestCase; public class StackTest extends TestCase { //required constructor public StackTest(String name) { super(name); } public void testDefaultConstructor() { Stack test = new Stack(); assert( test.isEmpty() ); } public void testSizeConstructor() { Stack test = new Stack(5); assert( test.isEmpty() ); } }
First part of the Stack
package example; public class Stack { int[] elements; int topElement = -1; public Stack() { this(10); } public Stack(int size) { elements = new int[size]; } public boolean isEmpty() { return topElement == -1; } }
Running JUnit
JUnit has three interfaces
Starting TestRunner
Make sure your classpath includes the code to tested
On Rohan use:
java junit.ui.LoadingTestRunner You get a window like:Enter the full name of the test class
Click on the Run button
If there are errors/failures select one and click on Show You will see a stack trace of the error With LoadingTestRunner you can recompile the Stack & StackTest classes without exiting LoadingTestRunner
Testing the Tests
If can be useful to modify the code to break the tests
package example; public class Stack { int[] elements; int topElement = -1; etc. public boolean isEmpty() { return topElement == 1; } }
One company had an automatic build and test cycle that ran at night. The daily build was created and all the tests were run at night. The test results were available first thing in the morning. One night the build process crashed, so the daily build was not made. Hence there was no code to test. Still 70% of the tests passed. If they had tested their tests, they would have discovered immediately that their tests were broken.
Test Fixtures
Before each test setUp() is run
After each test tearDown() is run
package example; import junit.framework.TestCase; public class StackTest extends TestCase { Stack test; public StackTest(String name) { super(name); } public void setUp() { test = new Stack(5); for (int k = 1; k <=5;k++) test.push( k); } public void testPushPop() { for (int k = 5; k >= 1; k--) assert( "Popping element " + k, test.pop() == k); } }
Suites – Multiple Test Classes
Multiple test classes can be run at the same time
Running AllTests in TestRunner runs the test in
package example; import junit.framework.TestSuite; public class AllTests { static public TestSuite suite() { TestSuite suite= new TestSuite(); try { suite.addTest(new TestSuite(StackTest.class)); suite.addTest(new TestSuite(QueueTest.class)); } catch (Exception e) { } return suite; } }
Using Main We can use main to run the test via textui.TestRunner
The command:
java example.AllTestswill run all the tests in StackTest & QueueTest
package example; import junit.framework.TestSuite; import junit.textui.TestRunner; public class AllTests { static public void main(String[] args) { TestRunner.main(args); } static public TestSuite suite() { same as last page } }
Just For Completeness The QueueTest and Queue classes exist but don't do much
package example; import junit.framework.TestCase; public class QueueTest extends TestCase { public QueueTest( String name) { super(name); } public void testConstructor() { Queue test = new Queue(); assert( test.isEmpty()); } }
package example; import java.util.Vector; public class Queue { Vector elements = new Vector(); public boolean isEmpty() { return elements.isEmpty(); } }
Why not just use print statements?
Using print statements does not scale
package example; public class StackTest { public static void main( String[] args ) { Stack test = new Stack(); System.out.println( "Expect: true Result: " + test.isEmpty()); test = new Stack(5); System.out.println( "Expect: true Result: " + test.isEmpty(); } }
What to Test
Everything that could possibly break
Test values
The Complete JUnit Example
Stack package example; public class Stack { int[] elements; int topElement = -1; public Stack() { this(10); } public Stack(int size) { elements = new int[size]; } public boolean isEmpty() { return topElement == -1; } public boolean isFull() { return topElement == elements.length-1; } public void push( int element) { topElement++; elements[topElement] = element; } public int pop() { return elements[topElement--]; } }
StackTest package example; import junit.framework.TestCase; public class StackTest extends TestCase { public StackTest(String name) { super(name); } public void testDefaultConstructor() { Stack test = new Stack(); assert( test.isEmpty() ); } public void testSizeConstructor() { Stack test = new Stack(5); assert( test.isEmpty() ); } public void testUnderflow() { Stack test = new Stack(512345); test.push( 1); test.pop(); try { test.pop(); fail( "Pop on empty stack passed"); } catch (Exception overflow) { } }
public void testPushAndFull() { Stack test = new Stack(5); assert("Is empty", test.isEmpty() ); assert("Empty stack claims full", test.isFull() == false); for (int k = 1; k <=5;k++) test.push( k); assert("Should not be empty", test.isEmpty() == false); assert( "Is full", test.isFull() ); try { test.push( 6); fail("Full stack accepted element"); } catch (Exception overflow) { } } public void testPushPop() { Stack test = new Stack(5); for (int k = 1; k <=5;k++) test.push( k); for (int k = 5; k >= 1; k--) assert( "Pop fail on element " + k, test.pop() == k); } }
Copyright ©, All rights reserved.
2000 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 30-Aug-00    Next