blob: 2cf8eecef241e60ba3ff2a84bfdef6cc9e93a58f [file] [log] [blame]
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="Author" content="Erich Gamma">
<title>JUnit Cookbook</title>
</head>
<body>
<h1>
<font color="#33FF33">J</font><font color="#CC0000">U</font>nit Cookbook</h1>
<p>
Kent Beck, Erich Gamma</p>
<hr WIDTH="100%">
<br>Here is a short cookbook showing you the steps you can follow in writing
and organizing your own tests using JUnit.
<h2>
Simple Test Case</h2>
How do you write testing code?
<p>The simplest way is as an expression in a debugger. You can change debug
expressions without recompiling, and you can wait to decide what to write
until you have seen the running objects. You can also write test expressions
as statements which print to the standard output stream. Both styles of
tests are limited because they require human judgment to analyze their
results. Also, they don't compose nicely- you can only execute one debug
expression at a time and a program with too many print statements causes
the dreaded "Scroll Blindness".
<p>JUnit tests do not require human judgment to interpret, and it is easy
to run many of them at the same time. When you need to test something,
here is what you do:
<ol>
<li>
Annotate a method with @org.junit.Test
<li>
When you want to check a value, import org.junit.Assert.* statically, call <tt>assertTrue</tt>() and pass a boolean
that is true if the test succeeds</li>
</ol>
For example, to test that the sum of two Moneys with the same currency
contains a value which is the sum of the values of the two Moneys, write:
<blockquote>
<pre><tt>@Test public void simpleAdd() {
&nbsp;&nbsp;&nbsp; Money m12CHF= new Money(12, &quot;CHF&quot;);&nbsp;
&nbsp;&nbsp;&nbsp; Money m14CHF= new Money(14, &quot;CHF&quot;);&nbsp;
&nbsp;&nbsp;&nbsp; Money expected= new Money(26, &quot;CHF&quot;);&nbsp;
&nbsp;&nbsp;&nbsp; Money result= m12CHF.add(m14CHF);&nbsp;
&nbsp;&nbsp;&nbsp; assertTrue(expected.equals(result));
}</tt></pre>
</blockquote>
If you want to write a test similar to one you have already written, write
a Fixture instead.
<h2>
Fixture</h2>
What if you have two or more tests that operate on the same or similar
sets of objects?
<p>Tests need to run against the background of a known set of objects.
This set of objects is called a test fixture. When you are writing tests
you will often find that you spend more time writing the code to set up
the fixture than you do in actually testing values.
<p>To some extent, you can make writing the fixture code easier by paying
careful attention to the constructors you write. However, a much bigger
savings comes from sharing fixture code. Often, you will be able to use
the same fixture for several different tests. Each case will send slightly
different messages or parameters to the fixture and will check for different
results.
<p>When you have a common fixture, here is what you do:
<ol>
<li>
Add a field for each part of the fixture</li>
<li>
Annotate a method with @org.junit.Before
and initialize the variables in that method</li>
<li>
Annotate a method with @org.junit.After
to release any permanent resources you allocated in setUp</li>
</ol>
For example, to write several test cases that want to work with different
combinations of 12 Swiss Francs, 14 Swiss Francs, and 28 US Dollars, first
create a fixture:
<pre><tt>public class MoneyTest {&nbsp;
&nbsp;&nbsp;&nbsp; private Money f12CHF;&nbsp;
&nbsp;&nbsp;&nbsp; private Money f14CHF;&nbsp;
&nbsp;&nbsp;&nbsp; private Money f28USD;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; @Before public void setUp() {&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f12CHF= new Money(12, &quot;CHF&quot;);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f14CHF= new Money(14, &quot;CHF&quot;);&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f28USD= new Money(28, &quot;USD&quot;);&nbsp;
&nbsp;&nbsp;&nbsp; }
}</tt></pre>
Once you have the Fixture in place, you can write as many Test Cases as
you'd like. Add as many test methods (annotated with @Test) as you'd like.
<h2>Running Tests</h2>
How do you run your tests and collect their results?
<p>Once you have tests, you'll want to run them. JUnit provides tools
to define the suite to be run and to display its results. To run tests and see the
results on the console, run this from a Java program:
<blockquote>
<pre>
org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);
</pre>
</blockquote>
or this from the command line, with both your test class and junit on the classpath:
<blockquote>
<pre>
java org.junit.runner.JUnitCore TestClass1.class [...other test classes...]
</pre>
</blockquote>
You make your JUnit 4 test classes accessible to a TestRunner designed to work with earlier versions of JUnit,
declare a static method <i>suite</i>
that returns a test.
<blockquote>
<pre><tt>public static junit.framework.Test suite() {&nbsp;
&nbsp;&nbsp;&nbsp; return new JUnit4TestAdapter(Example.class);&nbsp;
}</tt></pre>
</blockquote>
<h2>
Expected Exceptions</h2>
How do you verify that code throws exceptions as expected?
<p>Verifying that code completes normally is only part of programming. Making sure the code
behaves as expected in exceptional situations is part of the craft of programming too. For example:
<blockquote>
<pre><tt>new ArrayList&lt;Object&gt;().get(0);&nbsp;
</tt></pre>
</blockquote>
This code should throw an IndexOutOfBoundsException. The @Test annotation has an optional parameter "expected"
that takes as values subclasses of Throwable. If we wanted to verify that ArrayList throws the correct exception,
we would write:
<blockquote>
<pre><tt>@Test(expected= IndexOutOfBoundsException.class) public void empty() {&nbsp;
&nbsp;&nbsp;&nbsp; new ArrayList&lt;Object&gt;().get(0);&nbsp;
}</tt></pre>
</blockquote>
<hr WIDTH="100%">
</body>
</html>