JUnit Frequently
Asked Questions
Can't find the test classes when running them with
a TestRunner
How do I implement a test case for a thrown exception?
How do I organize my test cases?
I get a ClassNotFoundException when I
use the Swing or AWT TestRunners
Different
behavior in textui runner?
I get ClassCastException when I ran
my EJB tests.
Where are the
test runner properties documented?
How do I run setup code once
for all my TestCases?
I want to debug when a test fails
Can't find my test class when using a TestRunner
When you are getting a "Can't find 'TestClass'" error message when you
try to run your test with a TestRunner make sure that:
-
the junit.jar isn't installed in the extension directory of your
JDK installation. The junit.jar has to be on the class path.
-
the Test class you are trying to run is on the class path.
Notice, that the tests that come with the JUnit distribution are not included
inside the junit.jar but they reside in the installation directory. Therefore
make sure that the JUnit installation directory is on the class path.
How do I implement a test case for a thrown exception?
Catch the exception and if it isn't thrown call the fail method.
Fail signals the failure of a test case. Here is an example:
public void testIndexOutOfBoundsException() {
Vector v= new Vector(10)
try {
Object o= v.elementAt(v.size());
fail("Should raise
an ArrayIndexOutOfBoundsException");
} catch (ArrayIndexOutOfBoundsException e) {
}
}
or use the ExceptionTestCase as follows.
1) make your TestCase class a subclass of ExceptionTestCase.
2) write the test ignoring exceptions
public void testIndexOutOfBoundsException() {
Vector v= new Vector(10);
v.elementAt(v.size());
}
3) create the TestCase:
Test t= new ExceptionTestCase("testIndexOutOfBoundsException",
ArrayIndexOutOfBoundsException.class)
Looking at this again, the first way is simpler. Sigh...
How do I organize my Test Cases?
Here is one way:
-
create a test package for each of your application packages. For example,
for a package myapp.util define myapp.utiltest. Put all the
fixtures for the util package into this package.
-
in myapp.utiltest define a class which creates a suite with all the tests
in this package. To do so define a class AllTests which includes
a single static suite method. Here is an example:
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTest(Fixture1.suite());
suite.addTest(Fixture2.suite());
return suite;
}
-
define similar AllTests classes that create higher level suites containing
the suites from other test packages.
When the fixtures are in a separate test package the test cases don't
have access to the methods and fields with default visibility ("package
visible"). A variation of the above convention is to put all fixtures into
the application package itself. This gives the fixtures access to all the
package visible methods and fields. To separate the fixture classes from
the production classes put them into a separate directory that you then
add to the CLASSPATH. This makes it easy to ship the production classes
independent of the fixtures. Here is an example for how to do this:
-
put the fixtures classes for myapp.util into a TESTDIR\tests\myapp\util
directory,
-
add the tests directory to your CLASSPATH.
-
set CLASSPATH=%CLASSPATH%;TESTDIR\tests
How do I run setup code once for all my TestCases?
Wrap the top level suite in a subclass of TestSetup. Here is a sample AllTests.suite()
method:
public static Test suite() {
TestSuite suite= new TestSuite();
...add your tests and suites here...
TestSetup wrapper= new TestSetup(suite) {
public void setUp() {
oneTimeSetUp();
}
};
return wrapper;
}
I get a ClassNotFoundException when
I use the LoadingTestRunner
The UI test runners use a custom class loader to reload your code by default.
You can specify a list of excluded package prefixes that shouldn't be reloaded
for each test run. The idea is that you typically have a working set of
classes that you work with and that there is a set of classes that you
don't change. The list of package prefixes is defined in the properties
file junit/runner/excluded.properties. As we deliver it, this file
excludes the packages that come with jdk1.2 from reloading:
#
# The list of excluded package paths for the TestCaseClassLoader
#
excluded.0=sun.*
excluded.1=com.sun.*
excluded.2=org.omg.*
excluded.3=javax.*
excluded.4=sunw.*
If you are using additional jars from 3rd party vendors you can either:
-
update this file in the junit.jar and add your package paths or,
-
"patch" the junit.util.excluded.properties file with the CLASSPATH, that
is, put your customized version of this file in the class path before the
junit.jar. In this way your version will be loaded instead of the one that
comes with junit.
I want to debug when a test fails
Start the test runner under the debugger and configure the debugger so
that it catches the junit.framework.AssertionFailedError. How you do this
depends on the used IDE. Most Java debuggers support to stop the program
when a specific exception is fired. Notice, that this will only break into
the debugger when an "anticipated" assertion failed error occurs.
My
tests pass in the textui runner but they fail in the UI testrunners?
The UI test runner use a custom class loader by default to reload classes
for each run. The textui runner is using the system class loader. To disable
the custom class loader uncheck the "Reload classes for each run" check
box. The default setting can be changed in the junit.properties file.
Where are
the test runner properties documented?
See the JUnit Properties documentation.
I get a ClassCastException in
the Swing or AWT TestRunners
When I use the textui.TestRunner my setup runs OK. I get a ClassCastException
when I call PortableRemoteObject.narrow(SomeJndiObject,Some.class).
This is a consequence of the class reloading feature of the UI test
runners. There are different way to avoid this problem:
-
disable the reloading feature by either unchecking the check box "Reload
classes for each run" or by starting the TestRunner with the -reloading
option.
-
exclude some packages from reloading by adding them to the excluded.properties
file. For example add javax.ejb to the list of excluded packages.