Here’s a technique I sometimes use when I’m doing test-driven development (which is my preferred coding technique). Let’s say I’ve got a bunch of test cases that are all basically the same, but they have slightly different inputs and slightly different outputs. A typical test case might look like this:
public void testSomeTest1() { Results expected = new Results(...); Inputs input = new Inputs(...); assertEquals(expected, someObject.doStuff(input)); }
(In this example, someObject
was created as part of the setUp()
method)
Writing a whole heap of JUnit test cases like the above is tedious and dull. There’s a very simple technique you can use to make it a bit easier.
First, override the runTest()
protected method. It should look like this:
protected void runTest() { assertEquals(expected, someObject.doStuff(input)); }
Now add a constructor, like so:
private SomeTestCase(String name, Inputs input, Result result) { super(name); this.expected = result; this.inputs = input; }
Now, add a suite()
method. Like this:
public static Test suite() { Results[] expectedResults = { new Results(...), new Results(...), new Results(...) }; Inputs[] actualInputs = { new Inputs(...), new Inputs(...), new Inputs(...) }; TestSuite suite = new TestSuite(); for (int i = 0; i < expectedResults.length(); i++) { suite.add("SomeTestCase[" + i + "]", new SomeTestCase(actualInputs[i], expectedResults[i])); } }
The whole test case would look like this:
import junit.framework.*;
public class SomeTestCase extends TestCase {
private final Results expected;
private final Inputs inputs;
private SomeObject someObject;
private SomeTestCase(String name, Inputs input, Result result) {
super(name);
this.expected = result;
this.inputs = input;
}
public static Test suite() {
Results[] expectedResults = { new Results(…), new Results(…), new Results(…) };
Inputs[] actualInputs = { new Inputs(…), new Inputs(…), new Inputs(…) };
TestSuite suite = new TestSuite();
for (int i = 0; i < expectedResults.length(); i++) {
suite.add("SomeTestCase[" + i + "]", new SomeTestCase(actualInputs[i], expectedResults[i]));
}
}
protected void setUp() {
someObject = new SomeObject();
}
protected void runTest() {
assertEquals(expected, someObject.doStuff(input));
}
}
Wait a second, I hear some people ask. How does that work? There's no textXYZ
method.
That’s right. They’re not needed. But they are handy. JUnit essentially does a lot of things to make life a bit easier. For starters, uses reflection to create instances of the test case for each testXYZ
method, with the test method being the name of the test. The test name is then used by the default runTest()
implementation to invoke the test method. By overriding the runTest()
method, I removed a lot of the smarts, but at least I’ve got less typing.
A further extension to this technique is to load the expected results and inputs from a file. This allows you to define your test totally in an external file. Make it generic enough (say, with standard names for test classes and methods to test), and you’ve got a good start to defining a custom test language. While I wouldn’t use that sort of feature for unit testing, a lot of JUnit-based acceptance test tools look like this. You’ll find some at www.junit.org
hi,
i am new to junit.
i know how to install and how to work.
i am able to write testcases for small programs
when we r working with complex programs i am
getting ment troubles plz help me.
thanking you.
venkat.
Um, no I won’t help you. This isn’t the right forum.
I suggest you try the JUnit Yahoo group, but first, take the time to read this: http://www.catb.org/~esr/faqs/smart-questions.html