[go: up one dir, main page]

Menu

[1690a5]: / test / TEST-HOWTO  Maximize  Restore  History

Download this file

140 lines (90 with data), 4.9 kB

!---------------------------------------------!
! Unit Testing Guide                          !
!                                             !
!   to run the tests: 'ant testall'           !
!---------------------------------------------!

1. What is unit testing?

Writing code that will check whether a small unit of code works is called unit testing.

Example:

If we encode directions like this

protected static final int N = 0, NE = 1, E = 2, SE = 3, S = 4, SW = 5, W = 6, NW = 7;

and we want to write a function that returns the opposite direction. Usually we would 
write the implementation

public static int getOppositeDirection(int direction) {
  return (direction < 4) ? direction + 4 : direction - 4;
}

and then manually check that the method works correctly by either testing the compiled code 
within the application itself (in FreeCol this would mean verifying that each direction is
properly made opposite via the GUI output) or for a console-based application performing a
series of calls to the System.out.println function to output whether or not each case worked
properly.

Instead we can write source code that verifies whether the function behaves correctly:

        public void testGetOppositeDirection() throws FreeColException {
		assertEquals(Map.S, Map.getOppositeDirection(Map.N));
		assertEquals(Map.N, Map.getOppositeDirection(Map.S));
		assertEquals(Map.E, Map.getOppositeDirection(Map.W));
		assertEquals(Map.W, Map.getOppositeDirection(Map.E));
		assertEquals(Map.NE, Map.getOppositeDirection(Map.SW));
		assertEquals(Map.NW, Map.getOppositeDirection(Map.SE));
		assertEquals(Map.SW, Map.getOppositeDirection(Map.NE));
		assertEquals(Map.SE, Map.getOppositeDirection(Map.NW));
	}

Each assert statement will check whether the given condition holds true. If all assert 
statements succeed, the test passes (this may be indicated by a green bar in some IDEs) 
otherwise the test fails (this may be indicated with a red bar), telling you which line 
did not pass the assertion.

2. Why write tests?

* Verify that code works as expected in certain situations.

* To describe a bug to other developers, a test which fails can be cited as an example.

3. What are the benefits?

* Be able to run all the tests after a change to see if one broke existing functionality 
  ("regression test"), thus after enough tests have been written, it is easier to be 
  confident about changing the code.
  
* A test describes what a piece of code is supposed to do and often can help to understand 
  how it is supposed to be used.
  
* Since the test is written in source code it is much faster to run than manual tests in 
  the application.

4. Drawbacks?

* Writing test cases can be a lot of work.

* Testing of GUIs is especially difficult.

* One needs a lot of tests to get benefits like the regression checking.

5. How do I write test cases?

* Create a new class in the test/src folder that extends the class TestCase (import org.junit.*).
  All methods in this class that have a name that starts in "test...." will be executed.

* To check basic conditions use assertEquals, assertTrue, assertFalse, assertNotNull, etc...

* To check for exceptions to occur use the following construction:

try {
  // code that should throw exception
  ...
  fail()
} catch (FreeColException e){
  // Exception throws, thus okay
}

* To fail if an exception is thrown, just declare it:

public void testGetOppositeDirection() throws FreeColException {

6. How to run a test case?

a.) In Eclipse to run a test case:
  Right click the Test class -> Run As... -> JUnit Test

b.) On the command line the main directory (replace the text between $ $):
  java -cp $classpath for the class files from both src/ and test/src$;test/lib/junit.jar junit.swingui.TestRunnerorg $fully qualified name of the test class$

For instance if bin is your target directory and you want to run all tests

java -cp bin;test/lib/junit.jar junit.swingui.TestRunner net.sf.freecol.AllTests

c.) Using ant run:

If you have Apache Ant 1.7 or higher you can just run

ant testall

Otherwise:

ant -lib test/lib/junit.jar -Dtest=$qualified name of test class but ommitting net.sf.freecol$ test

for instance

ant -lib test/lib/junit.jar -Dtest=AllTests test

7. FAQ 

Q: What is the difference between unit and integration testing?
A: In unit testing the goal is to test small units in relative isolation, while integration 
   testing tries to figure out whether parts of the system work if put together. Both approaches 
   have their purpose and their strengths. In general one should try to first test code that has little
   dependencies to other code or remove the dependencies by using mock objects and later see 
   whether the code integrates with the rest of the system.

8. References:

[1] JUnit Test Infected: Programmers Love Writing Tests

http://junit.sourceforge.net/doc/testinfected/testing.htm

[2] JUnit Homepage

http://junit.org