JUnit TutorialIntroductionThis is not a thorough treatise on JUnit. But if you haven't used JUnit before, I suspect that it is about as much as you need. Getting JUnitGo to Sourceforge for downloads. The download button is towards the middle of the Web page, on the righthand side. At the time of writing the current version is 3.8.1, from September 2002. JUnit also comes bundled in with a lot of other software. In our experience, this kindness often causes trouble because of version inconsistencies or classpath problems. So we recommend that you
If you are using Maven, it will try to defeat you on this
score, downloading its own copy of JUnit and hiding it in
Don't forgot to remove the jar from
Installation and the Classpath
The jarfile needs to be installed where it will be on
whatever classpath you are using. If you are using JUnit
with Ant, there are very good reasons for putting the
Ant and JUnit jars in the same place, say in
Once again, you need to be sure that there is only one
set of Ant jars around (
It's important to keep in mind that there are at least three relevant classpath's -- the one seen by Java when it starts running Ant; the one seen by Ant; and the classpath passed by Ant to JUnit and Quilt when they are running tests.
Ant must be on the first classpath. The second classpath
is defined in
Setting Up Your Work DirectoriesWhile it is by no means necessary, it makes things much easier if unit tests are set up in a parallel hierarchy to that used for the software under test. The Quilt software is set up like this: src java org quilt cl QuiltClassLoader.java src test org quilt cl TestQuiltClassLoader.java The target directory, which the compiler writes compiled classes to, is organized in exactly the same way. Writing New Code
If you are writing new code from scratch, the approach sketched
out so far can make for very rapid software development. Each
class in the
JUnit TestsMost JUnit tests are written like this:
This gives you: package com.xyz.stuff; import junit.framework.*; public class TestStuff extends TestCase { public TestStuff(String name) { super(name); } protected void setUp() { } protected void tearDown() { } // there are normally many methods like this public void testX() { } }
While there are other JUnit classes,
setUpJUnit runs this method before running each of the tests.
Frequently you need to create a standard
fixture
to
run your code against. This might be something fairly complex,
perhaps an elaborate linked list or some other data structure
used for exercising your code. Generally you will want a
fresh copy of this for each test. You put the code for
generating this fixture in
tearDown
This is the companion to
In our experience
AssertionsAssertions are what JUnit is all about. The code you are testing is doing something. Your assertions will test that after running the software under test with a certain set of inputs, you will have a specified output. A typical assertion is something like // pattern: // assertCondition(failureMsg, expected, actual); assertEquals("cube factory is failing", 8, cubeIt (2)); You can omit the message, but this is generally undesirable. To keep things rolling along, you want a clear and unambiguous description of what failed; if you don't describe the failure, when it does go wrong you will spend time trying to guess what actually failed, or you will have to go back and add the message.
There are many JUnit assertions, all of them documented in
the Javadocs. In all cases, what is
All have two variants. For all except
In actual use, the most common assertion appears to be
We strongly recommend that instead of reading a lot about unit testing, you write a lot of test cases. After a while, it becomes second nature, and you have understood most of what is important regarding the subject. Then it makes a lot of sense to go back and read about it. Make Ant Do the Work for YouAs your software becomes bigger, tests take longer to run and it also becomes more difficult to track exactly what is going on. Use Ant's filesets to maintain your focus. This is easy to do if the software under test and the tests themselves are in parallel hierarchies. This allows you to casually switch between testing individual classes, testing all of the classes in a package, and running all of the tests, with just a few keystrokes in the editor: <batchtest todir="${test.report.dir}"> <fileset dir="${test.src.dir}"> <include name="**/TestStmtCoverage.java"/> <include name="**/TestRegistry.java"/> </fileset> </batchtest> <!-- other sets commonly tested; the first means 'all tests' <include name="**/*Test*.java"/> <include name="**/graph/Test*.java"/> <include name="**/TestA2O.java"/> <include name="**/TestBlockCode.java"/> <include name="**/TestClassFactory.java"/> -->
The build.xml fragment above runs only two tests,
Fixing Old CodeLife is more difficult if you are maintaining existing code. The practical approach is usually to introduce unit testing gradually, working towards the parallel directory hierarchies described above. This often encounters a good deal of opposition, partially because of the short-term expense and partially because of the intellectual and political investment in the status quo. If you persist, you will generally find that the code which most resists this approach is the code that most needs testing, because it is the buggiest. More InformationThere are two JUnit Web sites, one their own Web site and the other at Sourceforge . Both are very good. The first has links to Web sites describing dozens of other software packages using JUnit. The second is a tutorial with many references to other articles, papers, and Web sites. This material is copyright 2003 by James David Dixon ("Jim Dixon") and is made available under the Artistic License . |