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