158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpackage junit.framework;
258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.InvocationTargetException;
458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.Method;
558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.Modifier;
658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot/**
858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * A test case defines the fixture to run multiple tests. To define a test case<br>
958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * 1) implement a subclass of TestCase<br>
1058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * 2) define instance variables that store the state of the fixture<br>
1158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * 3) initialize the fixture state by overriding <code>setUp</code><br>
1258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * 4) clean-up after a test by overriding <code>tearDown</code>.<br>
1358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * Each test runs in its own fixture so there
1458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * can be no side effects among test runs.
1558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * Here is an example:
1658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
1758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * public class MathTest extends TestCase {
1858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *     protected double fValue1;
1958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *     protected double fValue2;
2058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *
2158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *    protected void setUp() {
2258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *         fValue1= 2.0;
2358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *         fValue2= 3.0;
2458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *     }
2558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * }
2658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
2758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *
2858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * For each test implement a method which interacts
2958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * with the fixture. Verify the expected results with assertions specified
3058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * by calling <code>assertTrue</code> with a boolean.
3158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
3258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *    public void testAdd() {
3358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *        double result= fValue1 + fValue2;
3458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *        assertTrue(result == 5.0);
3558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *    }
3658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
3758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * Once the methods are defined you can run them. The framework supports
3858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * both a static type safe and more dynamic way to run a test.
3958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * In the static way you override the runTest method and define the method to
4058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * be invoked. A convenient way to do so is with an anonymous inner class.
4158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
4258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestCase test= new MathTest("add") {
4358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *        public void runTest() {
4458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *            testAdd();
4558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *        }
4658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * };
4758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * test.run();
4858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
4958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * The dynamic way uses reflection to implement <code>runTest</code>. It dynamically finds
5058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * and invokes a method.
5158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * In this case the name of the test case has to correspond to the test method
5258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * to be run.
5358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
5458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestCase test= new MathTest("testAdd");
5558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * test.run();
5658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
5758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * The tests to be run can be collected into a TestSuite. JUnit provides
5858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * different <i>test runners</i> which can run a test suite and collect the results.
5958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * A test runner either expects a static method <code>suite</code> as the entry
6058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * point to get a test to run or it will extract the suite automatically.
6158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
6258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * public static Test suite() {
6358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *      suite.addTest(new MathTest("testAdd"));
6458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *      suite.addTest(new MathTest("testDivideByZero"));
6558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *      return suite;
6658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *  }
6758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
6858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * @see TestResult
6958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * @see TestSuite
7058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot */
7158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
7258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpublic abstract class TestCase extends Assert implements Test {
7358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
7458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * the name of the test case
7558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
7658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	private String fName;
7758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
7858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
7958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * No-arg constructor to enable serialization. This method
8058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * is not intended to be used by mere mortals without calling setName().
8158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
8258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public TestCase() {
8358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		fName= null;
8458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
8558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
8658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs a test case with the given name.
8758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
8858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public TestCase(String name) {
8958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		fName= name;
9058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
9158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
9258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Counts the number of test cases executed by run(TestResult result).
9358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
9458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public int countTestCases() {
9558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return 1;
9658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
9758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
9858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Creates a default TestResult object
9958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 *
10058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @see TestResult
10158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
10258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected TestResult createResult() {
10358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	    return new TestResult();
10458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
10558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
10658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * A convenience method to run this test, collecting the results with a
10758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * default TestResult object.
10858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 *
10958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @see TestResult
11058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
11158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public TestResult run() {
11258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		TestResult result= createResult();
11358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		run(result);
11458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return result;
11558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
11658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
11758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Runs the test case and collects the results in TestResult.
11858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
11958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void run(TestResult result) {
12058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		result.run(this);
12158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
12258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
12358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Runs the bare test sequence.
12458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @exception Throwable if any exception is thrown
12558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
12658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void runBare() throws Throwable {
12758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Throwable exception= null;
12858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		setUp();
12958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
13058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			runTest();
13158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (Throwable running) {
13258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			exception= running;
13358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
13458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		finally {
13558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			try {
13658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				tearDown();
13758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			} catch (Throwable tearingDown) {
13858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				if (exception == null) exception= tearingDown;
13958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			}
14058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
14158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (exception != null) throw exception;
14258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
14358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
14458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Override to run the test and assert its state.
14558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @exception Throwable if any exception is thrown
14658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
14758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected void runTest() throws Throwable {
14858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		assertNotNull(fName); // Some VMs crash when calling getMethod(null,null);
14958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Method runMethod= null;
15058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
15158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			// use getMethod to get all public inherited
15258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			// methods. getDeclaredMethods returns all
15358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			// methods of this class but excludes the
15458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			// inherited ones.
15558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			runMethod= getClass().getMethod(fName, (Class[])null);
15658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (NoSuchMethodException e) {
15758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			fail("Method \""+fName+"\" not found");
15858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
15958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (!Modifier.isPublic(runMethod.getModifiers())) {
16058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			fail("Method \""+fName+"\" should be public");
16158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
16258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
16358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
16458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			runMethod.invoke(this, (Object[])new Class[0]);
16558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
16658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		catch (InvocationTargetException e) {
16758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			e.fillInStackTrace();
16858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			throw e.getTargetException();
16958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
17058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		catch (IllegalAccessException e) {
17158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			e.fillInStackTrace();
17258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			throw e;
17358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
17458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
17558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
17658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Sets up the fixture, for example, open a network connection.
17758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * This method is called before a test is executed.
17858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
17958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected void setUp() throws Exception {
18058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
18158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
18258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Tears down the fixture, for example, close a network connection.
18358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * This method is called after a test is executed.
18458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
18558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected void tearDown() throws Exception {
18658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
18758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
18858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns a string representation of the test case
18958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
19058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public String toString() {
19158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	    return getName() + "(" + getClass().getName() + ")";
19258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
19358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
19458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Gets the name of a TestCase
19558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @return returns a String
19658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
19758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public String getName() {
19858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return fName;
19958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
20058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
20158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Sets the name of a TestCase
20258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @param name The name to set
20358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
20458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void setName(String name) {
20558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		fName= name;
20658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
20758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot}
208