summaryrefslogtreecommitdiffstats
path: root/junit4/doc
diff options
context:
space:
mode:
Diffstat (limited to 'junit4/doc')
-rw-r--r--junit4/doc/ReleaseNotes4.10.html93
-rw-r--r--junit4/doc/ReleaseNotes4.10.txt84
-rw-r--r--junit4/doc/ReleaseNotes4.4.html271
-rw-r--r--junit4/doc/ReleaseNotes4.4.txt295
-rw-r--r--junit4/doc/ReleaseNotes4.5.txt96
-rw-r--r--junit4/doc/ReleaseNotes4.6.html106
-rw-r--r--junit4/doc/ReleaseNotes4.6.txt100
-rw-r--r--junit4/doc/ReleaseNotes4.7.html229
-rw-r--r--junit4/doc/ReleaseNotes4.7.txt194
-rw-r--r--junit4/doc/ReleaseNotes4.8.1.html9
-rw-r--r--junit4/doc/ReleaseNotes4.8.1.txt7
-rw-r--r--junit4/doc/ReleaseNotes4.8.2.html10
-rw-r--r--junit4/doc/ReleaseNotes4.8.2.txt8
-rw-r--r--junit4/doc/ReleaseNotes4.8.html59
-rw-r--r--junit4/doc/ReleaseNotes4.8.txt56
-rw-r--r--junit4/doc/ReleaseNotes4.9.1.txt14
-rw-r--r--junit4/doc/ReleaseNotes4.9.html96
-rw-r--r--junit4/doc/ReleaseNotes4.9.txt89
-rw-r--r--junit4/doc/building-junit.txt19
-rw-r--r--junit4/doc/cookbook/cookbook.htm143
-rw-r--r--junit4/doc/cookbook/logo.gifbin0 -> 964 bytes
-rw-r--r--junit4/doc/cookstour/Image1.gifbin0 -> 1820 bytes
-rw-r--r--junit4/doc/cookstour/Image2.gifbin0 -> 2490 bytes
-rw-r--r--junit4/doc/cookstour/Image3.gifbin0 -> 2946 bytes
-rw-r--r--junit4/doc/cookstour/Image4.gifbin0 -> 3694 bytes
-rw-r--r--junit4/doc/cookstour/Image5.gifbin0 -> 4858 bytes
-rw-r--r--junit4/doc/cookstour/Image6.gifbin0 -> 8950 bytes
-rw-r--r--junit4/doc/cookstour/Image7.gifbin0 -> 5295 bytes
-rw-r--r--junit4/doc/cookstour/cookstour.htm668
-rw-r--r--junit4/doc/faq/faq.htm2380
-rw-r--r--junit4/doc/homepage.html115
-rw-r--r--junit4/doc/index.htm21
-rw-r--r--junit4/doc/markdown.sh1
-rw-r--r--junit4/doc/testinfected/IMG00001.GIFbin0 -> 6426 bytes
-rw-r--r--junit4/doc/testinfected/IMG00002.GIFbin0 -> 6934 bytes
-rw-r--r--junit4/doc/testinfected/IMG00003.GIFbin0 -> 5992 bytes
-rw-r--r--junit4/doc/testinfected/logo.gifbin0 -> 964 bytes
-rw-r--r--junit4/doc/testinfected/testing.htm617
38 files changed, 5780 insertions, 0 deletions
diff --git a/junit4/doc/ReleaseNotes4.10.html b/junit4/doc/ReleaseNotes4.10.html
new file mode 100644
index 0000000..ebf4174
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.10.html
@@ -0,0 +1,93 @@
+<h2>Summary of Changes in version 4.10 [unreleased!]</h2>
+
+<p>A full summary of commits between 4.9 and 4.10 is on <a href="https://github.com/KentBeck/junit/compare/r4.9...4.10">github</a></p>
+
+<h3>junit-dep has correct contents</h3>
+
+<p>junit-dep-4.9.jar incorrectly contained hamcrest classes, which could lead to version conflicts in projects that depend on hamcrest directly. This is fixed in 4.10 [@dsaff, closing gh-309]</p>
+
+<h3>RuleChain</h3>
+
+<p>The RuleChain rule allows ordering of TestRules:</p>
+
+<pre><code>public static class UseRuleChain {
+ @Rule
+ public TestRule chain= RuleChain
+ .outerRule(new LoggingRule("outer rule")
+ .around(new LoggingRule("middle rule")
+ .around(new LoggingRule("inner rule");
+
+ @Test
+ public void example() {
+ assertTrue(true);
+ }
+}
+</code></pre>
+
+<p>writes the log</p>
+
+<pre><code>starting outer rule
+starting middle rule
+starting inner rule
+finished inner rule
+finished middle rule
+finished outer rule
+</code></pre>
+
+<h3>TemporaryFolder</h3>
+
+<ul>
+<li><code>TemporaryFolder#newFolder(String... folderNames)</code> creates recursively deep temporary folders
+[@rodolfoliviero, closing gh-283]</li>
+<li><code>TemporaryFolder#newFile()</code> creates a randomly named new file, and <code>#newFolder()</code> creates a randomly named new folder
+[@Daniel Rothmaler, closing gh-299]</li>
+</ul>
+
+<h3>Theories</h3>
+
+<p>The <code>Theories</code> runner does not anticipate theory parameters that have generic
+types, as reported by github#64. Fixing this won't happen until <code>Theories</code> is
+moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
+necessary machinery to the runner classes, and deprecates a method that only
+the <code>Theories</code> runner uses, <code>FrameworkMethod</code>#producesType().
+The Common Public License that JUnit is released under is now included
+in the source repository.</p>
+
+<p>Thanks to <code>@pholser</code> for identifying a potential resolution for github#64
+and initiating work on it.</p>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>Built-in Rules implementations
+<ul>
+<li>TemporaryFolder should not create files in the current working directory if applying the rule fails
+[@orfjackal, fixing gh-278]</li>
+<li>TestWatcher and TestWatchman should not call failed for AssumptionViolatedExceptions
+[@stefanbirkner, fixing gh-296]</li>
+</ul></li>
+<li>Javadoc bugs
+<ul>
+<li>Assert documentation [@stefanbirkner, fixing gh-134]</li>
+<li>ClassRule [@stefanbirkner, fixing gh-254]</li>
+<li>Parameterized [@stefanbirkner, fixing gh-89]</li>
+<li>Parameterized, again [@orfjackal, fixing gh-285]</li>
+</ul></li>
+<li>Miscellaneous
+<ul>
+<li>Useless code in RunAfters [@stefanbirkner, fixing gh-289]</li>
+<li>Parameterized test classes should be able to have <code>@Category</code> annotations
+[@dsaff, fixing gh-291]</li>
+<li>Error count should be initialized in junit.tests.framework.TestListenerTest [@stefanbirkner, fixing gh-225]</li>
+<li>AssertionFailedError constructor shouldn't call super with null message [@stefanbirkner, fixing gh-318]</li>
+<li>Clearer error message for non-static inner test classes [@stefanbirkner, fixing gh-42]</li>
+</ul></li>
+</ul>
+
+<h3>Minor changes</h3>
+
+<ul>
+<li>Description, Result and Failure are Serializable [@ephox-rob, closing gh-101]</li>
+<li>FailOnTimeout is reusable, allowing for retrying Rules [@stefanbirkner, closing gh-265]</li>
+<li>New <code>ErrorCollector.checkThat</code> overload, that allows you to specify a reason [@drothmaler, closing gh-300]</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.10.txt b/junit4/doc/ReleaseNotes4.10.txt
new file mode 100644
index 0000000..ccf8625
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.10.txt
@@ -0,0 +1,84 @@
+## Summary of Changes in version 4.10 ##
+
+Thanks to a full cast of contributors of bug fixes and new features.
+
+A full summary of commits between 4.9 and 4.10 is on [github](https://github.com/KentBeck/junit/compare/r4.9...4.10)
+
+### junit-dep has correct contents ###
+
+junit-dep-4.9.jar incorrectly contained hamcrest classes, which could lead to version conflicts in projects that depend on hamcrest directly. This is fixed in 4.10 [@dsaff, closing gh-309]
+
+### RuleChain ###
+
+The RuleChain rule allows ordering of TestRules:
+
+ public static class UseRuleChain {
+ @Rule
+ public TestRule chain= RuleChain
+ .outerRule(new LoggingRule("outer rule")
+ .around(new LoggingRule("middle rule")
+ .around(new LoggingRule("inner rule");
+
+ @Test
+ public void example() {
+ assertTrue(true);
+ }
+ }
+
+writes the log
+
+ starting outer rule
+ starting middle rule
+ starting inner rule
+ finished inner rule
+ finished middle rule
+ finished outer rule
+
+### TemporaryFolder ###
+
+- `TemporaryFolder#newFolder(String... folderNames)` creates recursively deep temporary folders
+ [@rodolfoliviero, closing gh-283]
+- `TemporaryFolder#newFile()` creates a randomly named new file, and `#newFolder()` creates a randomly named new folder
+ [@Daniel Rothmaler, closing gh-299]
+
+### Theories ###
+
+The `Theories` runner does not anticipate theory parameters that have generic
+types, as reported by github#64. Fixing this won't happen until `Theories` is
+moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
+necessary machinery to the runner classes, and deprecates a method that only
+the `Theories` runner uses, `FrameworkMethod`#producesType().
+The Common Public License that JUnit is released under is now included
+in the source repository.
+
+Thanks to `@pholser` for identifying a potential resolution for github#64
+and initiating work on it.
+
+### Bug fixes ###
+
+- Built-in Rules implementations
+ - TemporaryFolder should not create files in the current working directory if applying the rule fails
+ [@orfjackal, fixing gh-278]
+ - TestWatcher and TestWatchman should not call failed for AssumptionViolatedExceptions
+ [@stefanbirkner, fixing gh-296]
+- Javadoc bugs
+ - Assert documentation [@stefanbirkner, fixing gh-134]
+ - ClassRule [@stefanbirkner, fixing gh-254]
+ - Parameterized [@stefanbirkner, fixing gh-89]
+ - Parameterized, again [@orfjackal, fixing gh-285]
+- Miscellaneous
+ - Useless code in RunAfters [@stefanbirkner, fixing gh-289]
+ - Parameterized test classes should be able to have `@Category` annotations
+ [@dsaff, fixing gh-291]
+ - Error count should be initialized in junit.tests.framework.TestListenerTest [@stefanbirkner, fixing gh-225]
+ - AssertionFailedError constructor shouldn't call super with null message [@stefanbirkner, fixing gh-318]
+ - Clearer error message for non-static inner test classes [@stefanbirkner, fixing gh-42]
+
+### Minor changes ###
+
+- Description, Result and Failure are Serializable [@ephox-rob, closing gh-101]
+- FailOnTimeout is reusable, allowing for retrying Rules [@stefanbirkner, closing gh-265]
+- New `ErrorCollector.checkThat` overload, that allows you to specify a reason [@drothmaler, closing gh-300]
+
+
+
diff --git a/junit4/doc/ReleaseNotes4.4.html b/junit4/doc/ReleaseNotes4.4.html
new file mode 100644
index 0000000..3736b46
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.4.html
@@ -0,0 +1,271 @@
+<h2>Summary of Changes in version 4.5</h2>
+
+<h3>Categories</h3>
+
+<p>Each test method and test class can be annotated as belonging to a <em>category</em>:</p>
+
+<pre><code>public static class SomeUITests {
+ @Category(UserAvailable.class)
+ @Test
+ public void askUserToPressAKey() { }
+
+ @Test
+ public void simulatePressingKey() { }
+}
+
+@Category(InternetConnected.class)
+public static class InternetTests {
+ @Test
+ public void pingServer() { }
+}
+</code></pre>
+
+<p>To run all of the tests in a particular category, you must currently explicitly create a custom request:</p>
+
+<pre><code>new JUnitCore().run(Request.aClass(SomeUITests.class).inCategories(UserAvailable.class));
+</code></pre>
+
+<p>This feature will very likely be improved before the final release of JUnit 4.5</p>
+
+<h3>Miscellaneous</h3>
+
+<ul>
+<li><p><code>@Before</code> and <code>@After</code> methods are run before and after each set of attempted parameters
+on a Theory</p></li>
+<li><p>Refactoring removed duplication that used to exist in classes MethodRoadie and ClassRoadie</p></li>
+<li><p>Exposed API <code>ParameterSignature.getType()</code></p></li>
+</ul>
+
+<h2>Summary of Changes in version 4.4</h2>
+
+<p>JUnit is designed to efficiently capture developers' intentions about
+their code, and quickly check their code matches those intentions.
+Over the last year, we've been talking about what things developers
+would like to say about their code that have been difficult in the
+past, and how we can make them easier.</p>
+
+<p><a href="http://sourceforge.net/project/showfiles.php?group_id=15278">Download</a></p>
+
+<h3>assertThat</h3>
+
+<p>Two years ago, Joe Walnes built a <a href="http://joe.truemesh.com/blog/000511.html">new assertion mechanism</a> on top of what was
+then <a href="http://www.jmock.org/download.html">JMock 1</a>. The method name was <code>assertThat</code>, and the syntax looked like this:</p>
+
+<pre><code>assertThat(x, is(3));
+assertThat(x, is(not(4)));
+assertThat(responseString, either(containsString("color")).or(containsString("colour")));
+assertThat(myList, hasItem("3"));
+</code></pre>
+
+<p>More generally:</p>
+
+<pre><code>assertThat([value], [matcher statement]);
+</code></pre>
+
+<p>Advantages of this assertion syntax include:</p>
+
+<ul>
+<li><p>More readable and typeable: this syntax allows you to think in terms of subject, verb, object
+(assert "x is 3") rather than <code>assertEquals</code>, which uses verb, object, subject (assert "equals 3 x")</p></li>
+<li><p>Combinations: any matcher statement <code>s</code> can be negated (<code>not(s)</code>), combined (<code>either(s).or(t)</code>),
+mapped to a collection (<code>each(s)</code>), or used in custom combinations (<code>afterFiveSeconds(s)</code>)</p></li>
+<li><p>Readable failure messages. Compare</p>
+
+<pre><code>assertTrue(responseString.contains("color") || responseString.contains("colour"));
+// ==&gt; failure message:
+// java.lang.AssertionError:
+
+
+assertThat(responseString, anyOf(containsString("color"), containsString("colour")));
+// ==&gt; failure message:
+// java.lang.AssertionError:
+// Expected: (a string containing "color" or a string containing "colour")
+// got: "Please choose a font"
+</code></pre></li>
+<li><p>Custom Matchers. By implementing the <code>Matcher</code> interface yourself, you can get all of the
+above benefits for your own custom assertions.</p></li>
+<li><p>For a more thorough description of these points, see <a href="http://joe.truemesh.com/blog/000511.html">Joe Walnes's
+original post</a>.</p></li>
+</ul>
+
+<p>We have decided to include this API directly in JUnit.
+It's an extensible and readable syntax, and it enables
+new features, like <a href="#assumptions">assumptions</a> and <a href="#theories">theories</a>.</p>
+
+<p>Some notes:</p>
+
+<ul>
+<li>The old assert methods are never, ever, going away. Developers may
+continue using the old <code>assertEquals</code>, <code>assertTrue</code>, and so on.</li>
+<li><p>The second parameter of an <code>assertThat</code> statement is a <code>Matcher</code>.
+We include the Matchers we want as static imports, like this:</p>
+
+<pre><code>import static org.hamcrest.CoreMatchers.is;
+</code></pre>
+
+<p>or:</p>
+
+<pre><code>import static org.hamcrest.CoreMatchers.*;
+</code></pre></li>
+<li><p>Manually importing <code>Matcher</code> methods can be frustrating. <a href="http://www.eclipse.org/downloads/">Eclipse 3.3</a> includes the ability to
+define
+"Favorite" classes to import static methods from, which makes it easier
+(Search for "Favorites" in the Preferences dialog).
+We expect that support for static imports will improve in all Java IDEs in the future.</p></li>
+<li><p>To allow compatibility with a wide variety of possible matchers,
+we have decided to include the classes from hamcrest-core,
+from the <a href="http://code.google.com/p/hamcrest/">Hamcrest</a> project. This is the first time that
+third-party classes have been included in JUnit. </p></li>
+<li><p>JUnit currently ships with a few matchers, defined in
+<code>org.hamcrest.CoreMatchers</code> and <code>org.junit.matchers.JUnitMatchers</code>. <br />
+To use many, many more, consider downloading the <a href="http://hamcrest.googlecode.com/files/hamcrest-all-1.1.jar">full hamcrest package</a>.</p></li>
+<li><p>JUnit contains special support for comparing string and array
+values, giving specific information on how they differ. This is not
+yet available using the <code>assertThat</code> syntax, but we hope to bring
+the two assert methods into closer alignment in future releases.</p></li>
+</ul>
+
+<p><a name="assumptions" /></p>
+
+<h3>Assumptions</h3>
+
+<p>Ideally, the developer writing a test has control of all of the forces that might cause a test to fail.
+If this isn't immediately possible, making dependencies explicit can often improve a design. <br />
+For example, if a test fails when run in a different locale than the developer intended,
+it can be fixed by explicitly passing a locale to the domain code.</p>
+
+<p>However, sometimes this is not desirable or possible. <br />
+It's good to be able to run a test against the code as it is currently written,
+implicit assumptions and all, or to write a test that exposes a known bug.
+For these situations, JUnit now includes the ability to express "assumptions":</p>
+
+<pre><code>import static org.junit.Assume.*
+
+@Test public void filenameIncludesUsername() {
+ assumeThat(File.separatorChar, is('/'));
+ assertThat(new User("optimus").configFileName(), is("configfiles/optimus.cfg"));
+}
+
+@Test public void correctBehaviorWhenFilenameIsNull() {
+ assumeTrue(bugFixed("13356")); // bugFixed is not included in JUnit
+ assertThat(parse(null), is(new NullDocument()));
+}
+</code></pre>
+
+<p>With this release, a failed assumption will lead to the test being marked as passing,
+regardless of what the code below the assumption may assert.
+In the future, this may change, and a failed assumption may lead to the test being ignored:
+however, third-party runners do not currently allow this option.</p>
+
+<p>We have included <code>assumeTrue</code> for convenience, but thanks to the
+inclusion of Hamcrest, we do not need to create <code>assumeEquals</code>,
+<code>assumeSame</code>, and other analogues to the <code>assert*</code> methods. All of
+those functionalities are subsumed in <code>assumeThat</code>, with the appropriate
+matcher.</p>
+
+<p>A failing assumption in a <code>@Before</code> or <code>@BeforeClass</code> method will have the same effect
+as a failing assumption in each <code>@Test</code> method of the class.</p>
+
+<p><a name="theories" /></p>
+
+<h3>Theories</h3>
+
+<p>More flexible and expressive assertions, combined with the ability to
+state assumptions clearly, lead to a new kind of statement of intent,
+which we call a "Theory". A test captures the intended behavior in
+one particular scenario. A theory captures some aspect of the
+intended behavior in possibly
+infinite numbers of potential scenarios. For example:</p>
+
+<pre><code>@RunWith(Theories.class)
+public class UserTest {
+ @DataPoint public static String GOOD_USERNAME = "optimus";
+ @DataPoint public static String USERNAME_WITH_SLASH = "optimus/prime";
+
+ @Theory public void filenameIncludesUsername(String username) {
+ assumeThat(username, not(containsString("/")));
+ assertThat(new User(username).configFileName(), containsString(username));
+ }
+}
+</code></pre>
+
+<p>This makes it clear that the user's filename should be included in the
+config file name, only if it doesn't contain a slash. Another test
+or theory might define what happens when a username does contain a slash.</p>
+
+<p><code>UserTest</code> will attempt to run <code>filenameIncludesUsername</code> on
+every compatible <code>DataPoint</code> defined in the class. If any of the
+assumptions fail, the data point is silently ignored. If all of the
+assumptions pass, but an assertion fails, the test fails.</p>
+
+<p>The support for Theories has been absorbed from the <a href="http://popper.tigris.org">Popper</a>
+project, and <a href="http://popper.tigris.org/tutorial.html">more complete documentation</a> can be found
+there.</p>
+
+<p>Defining general statements in this way can jog the developer's memory
+about other potential data points and tests, also allows <a href="http://www.junitfactory.org">automated
+tools</a> to <a href="http://shareandenjoy.saff.net/2007/04/popper-and-junitfactory.html">search</a> for new, unexpected data
+points that expose bugs.</p>
+
+<h3>Other changes</h3>
+
+<p>This release contains other bug fixes and new features. Among them:</p>
+
+<ul>
+<li><p>Annotated descriptions</p>
+
+<p>Runner UIs, Filters, and Sorters operate on Descriptions of test
+methods and test classes. These Descriptions now include the
+annotations on the original Java source element, allowing for richer
+display of test results, and easier development of annotation-based
+filters.</p></li>
+<li><p>Bug fix (1715326): assertEquals now compares all Numbers using their
+native implementation of <code>equals</code>. This assertion, which passed in
+4.3, will now fail:</p>
+
+<pre><code>assertEquals(new Integer(1), new Long(1));
+</code></pre>
+
+<p>Non-integer Numbers (Floats, Doubles, BigDecimals, etc),
+which were compared incorrectly in 4.3, are now fixed.</p></li>
+<li><p><code>assertEquals(long, long)</code> and <code>assertEquals(double, double)</code> have
+been re-introduced to the <code>Assert</code> class, to take advantage of
+Java's native widening conversions. Therefore, this still passes:</p>
+
+<pre><code>assertEquals(1, 1L);
+</code></pre></li>
+<li><p>The default runner for JUnit 4 test classes has been refactored.
+The old version was named <code>TestClassRunner</code>, and the new is named
+<code>JUnit4ClassRunner</code>. Likewise, <code>OldTestClassRunner</code> is now
+<code>JUnit3ClassRunner</code>. The new design allows variations in running
+individual test classes to be expressed with fewer custom classes.
+For a good example, see the source to
+<code>org.junit.experimental.theories.Theories</code>.</p></li>
+<li><p>The rules for determining which runner is applied by default to a
+test class have been simplified:</p>
+
+<ol>
+<li><p>If the class has a <code>@RunWith</code> annotation, the annotated runner
+class is used.</p></li>
+<li><p>If the class can be run with the JUnit 3 test runner (it
+subclasses <code>TestCase</code>, or contains a <code>public static Test suite()</code>
+method), JUnit38ClassRunner is used.</p></li>
+<li><p>Otherwise, JUnit4ClassRunner is used.</p></li>
+</ol>
+
+<p>This default guess can always be overridden by an explicit
+<code>@RunWith(JUnit4ClassRunner.class)</code> or
+<code>@RunWith(JUnit38ClassRunner.class)</code> annotation.</p>
+
+<p>The old class names <code>TestClassRunner</code> and <code>OldTestClassRunner</code>
+remain as deprecated.</p></li>
+<li><p>Bug fix (1739095): Filters and Sorters work correctly on test
+classes that contain a <code>suite</code> method like:</p>
+
+<pre><code>public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(MyTest.class);
+}
+</code></pre></li>
+<li><p>Bug fix (1745048): @After methods are now correctly called
+after a test method times out.</p></li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.4.txt b/junit4/doc/ReleaseNotes4.4.txt
new file mode 100644
index 0000000..98d9ddd
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.4.txt
@@ -0,0 +1,295 @@
+## Summary of Changes in version 4.5 ##
+
+### Categories ###
+Each test method and test class can be annotated as belonging to a _category_:
+
+ public static class SomeUITests {
+ @Category(UserAvailable.class)
+ @Test
+ public void askUserToPressAKey() { }
+
+ @Test
+ public void simulatePressingKey() { }
+ }
+
+ @Category(InternetConnected.class)
+ public static class InternetTests {
+ @Test
+ public void pingServer() { }
+ }
+
+To run all of the tests in a particular category, you must currently explicitly create a custom request:
+
+ new JUnitCore().run(Request.aClass(SomeUITests.class).inCategories(UserAvailable.class));
+
+This feature will very likely be improved before the final release of JUnit 4.5
+
+### Theories ###
+
+- `@Before` and `@After` methods are run before and after each set of attempted parameters
+ on a Theory, and each set of parameters is run on a new instance of the test class.
+
+- Exposed API's `ParameterSignature.getType()` and `ParameterSignature.getAnnotations()`
+
+- An array of data points can be introduced by a field or method marked with the new annotation `@DataPoints`
+
+- The Theories custom runner has been refactored to make it easier to extend
+
+### JUnit 4 Runner API ###
+
+- There has been a drastic rewrite of the API for custom Runners in 4.5. This
+ needs to be written up separately before release.
+
+- Tests with failed assumptions are now marked as Ignored, rather than silently passing.
+ This may change behavior in some client tests, and also will require some new support
+ on the part of IDE's.
+
+## Summary of Changes in version 4.4 ##
+
+JUnit is designed to efficiently capture developers' intentions about
+their code, and quickly check their code matches those intentions.
+Over the last year, we've been talking about what things developers
+would like to say about their code that have been difficult in the
+past, and how we can make them easier.
+
+[Download][]
+
+[Download]: http://sourceforge.net/project/showfiles.php?group_id=15278
+
+### assertThat ###
+
+Two years ago, Joe Walnes built a [new assertion mechanism][walnes] on top of what was
+then [JMock 1][]. The method name was `assertThat`, and the syntax looked like this:
+
+[walnes]: http://joe.truemesh.com/blog/000511.html
+[JMock 1]: http://www.jmock.org/download.html
+
+ assertThat(x, is(3));
+ assertThat(x, is(not(4)));
+ assertThat(responseString, either(containsString("color")).or(containsString("colour")));
+ assertThat(myList, hasItem("3"));
+
+More generally:
+
+ assertThat([value], [matcher statement]);
+
+Advantages of this assertion syntax include:
+
+- More readable and typeable: this syntax allows you to think in terms of subject, verb, object
+ (assert "x is 3") rather than `assertEquals`, which uses verb, object, subject (assert "equals 3 x")
+
+- Combinations: any matcher statement `s` can be negated (`not(s)`), combined (`either(s).or(t)`),
+ mapped to a collection (`each(s)`), or used in custom combinations (`afterFiveSeconds(s)`)
+
+- Readable failure messages. Compare
+
+ assertTrue(responseString.contains("color") || responseString.contains("colour"));
+ // ==> failure message:
+ // java.lang.AssertionError:
+
+ assertThat(responseString, anyOf(containsString("color"), containsString("colour")));
+ // ==> failure message:
+ // java.lang.AssertionError:
+ // Expected: (a string containing "color" or a string containing "colour")
+ // got: "Please choose a font"
+
+- Custom Matchers. By implementing the `Matcher` interface yourself, you can get all of the
+ above benefits for your own custom assertions.
+
+- For a more thorough description of these points, see [Joe Walnes's
+ original post][walnes].
+
+We have decided to include this API directly in JUnit.
+It's an extensible and readable syntax, and it enables
+new features, like [assumptions][] and [theories][].
+
+[assumptions]: #assumptions
+[theories]: #theories
+
+Some notes:
+
+- The old assert methods are never, ever, going away. Developers may
+ continue using the old `assertEquals`, `assertTrue`, and so on.
+- The second parameter of an `assertThat` statement is a `Matcher`.
+ We include the Matchers we want as static imports, like this:
+
+ import static org.hamcrest.CoreMatchers.is;
+
+ or:
+
+ import static org.hamcrest.CoreMatchers.*;
+
+- Manually importing `Matcher` methods can be frustrating. [Eclipse 3.3][] includes the ability to
+ define
+ "Favorite" classes to import static methods from, which makes it easier
+ (Search for "Favorites" in the Preferences dialog).
+ We expect that support for static imports will improve in all Java IDEs in the future.
+
+[Eclipse 3.3]: http://www.eclipse.org/downloads/
+
+- To allow compatibility with a wide variety of possible matchers,
+ we have decided to include the classes from hamcrest-core,
+ from the [Hamcrest][] project. This is the first time that
+ third-party classes have been included in JUnit.
+
+[Hamcrest]: http://code.google.com/p/hamcrest/
+
+- JUnit currently ships with a few matchers, defined in
+ `org.hamcrest.CoreMatchers` and `org.junit.matchers.JUnitMatchers`.
+ To use many, many more, consider downloading the [full hamcrest package][].
+
+[full hamcrest package]: http://hamcrest.googlecode.com/files/hamcrest-all-1.1.jar
+
+- JUnit contains special support for comparing string and array
+ values, giving specific information on how they differ. This is not
+ yet available using the `assertThat` syntax, but we hope to bring
+ the two assert methods into closer alignment in future releases.
+
+<a name="assumptions" />
+### Assumptions ###
+
+Ideally, the developer writing a test has control of all of the forces that might cause a test to fail.
+If this isn't immediately possible, making dependencies explicit can often improve a design.
+For example, if a test fails when run in a different locale than the developer intended,
+it can be fixed by explicitly passing a locale to the domain code.
+
+However, sometimes this is not desirable or possible.
+It's good to be able to run a test against the code as it is currently written,
+implicit assumptions and all, or to write a test that exposes a known bug.
+For these situations, JUnit now includes the ability to express "assumptions":
+
+ import static org.junit.Assume.*
+
+ @Test public void filenameIncludesUsername() {
+ assumeThat(File.separatorChar, is('/'));
+ assertThat(new User("optimus").configFileName(), is("configfiles/optimus.cfg"));
+ }
+
+ @Test public void correctBehaviorWhenFilenameIsNull() {
+ assumeTrue(bugFixed("13356")); // bugFixed is not included in JUnit
+ assertThat(parse(null), is(new NullDocument()));
+ }
+
+With this release, a failed assumption will lead to the test being marked as passing,
+regardless of what the code below the assumption may assert.
+In the future, this may change, and a failed assumption may lead to the test being ignored:
+however, third-party runners do not currently allow this option.
+
+We have included `assumeTrue` for convenience, but thanks to the
+inclusion of Hamcrest, we do not need to create `assumeEquals`,
+`assumeSame`, and other analogues to the `assert*` methods. All of
+those functionalities are subsumed in `assumeThat`, with the appropriate
+matcher.
+
+A failing assumption in a `@Before` or `@BeforeClass` method will have the same effect
+as a failing assumption in each `@Test` method of the class.
+
+<a name="theories" />
+### Theories ###
+
+More flexible and expressive assertions, combined with the ability to
+state assumptions clearly, lead to a new kind of statement of intent,
+which we call a "Theory". A test captures the intended behavior in
+one particular scenario. A theory captures some aspect of the
+intended behavior in possibly
+infinite numbers of potential scenarios. For example:
+
+ @RunWith(Theories.class)
+ public class UserTest {
+ @DataPoint public static String GOOD_USERNAME = "optimus";
+ @DataPoint public static String USERNAME_WITH_SLASH = "optimus/prime";
+
+ @Theory public void filenameIncludesUsername(String username) {
+ assumeThat(username, not(containsString("/")));
+ assertThat(new User(username).configFileName(), containsString(username));
+ }
+ }
+
+This makes it clear that the user's filename should be included in the
+config file name, only if it doesn't contain a slash. Another test
+or theory might define what happens when a username does contain a slash.
+
+`UserTest` will attempt to run `filenameIncludesUsername` on
+every compatible `DataPoint` defined in the class. If any of the
+assumptions fail, the data point is silently ignored. If all of the
+assumptions pass, but an assertion fails, the test fails.
+
+The support for Theories has been absorbed from the [Popper][]
+project, and [more complete documentation][popper-docs] can be found
+there.
+
+[Popper]: http://popper.tigris.org
+[popper-docs]: http://popper.tigris.org/tutorial.html
+
+Defining general statements in this way can jog the developer's memory
+about other potential data points and tests, also allows [automated
+tools][junit-factory] to [search][my-blog] for new, unexpected data
+points that expose bugs.
+
+[junit-factory]: http://www.junitfactory.org
+[my-blog]: http://shareandenjoy.saff.net/2007/04/popper-and-junitfactory.html
+
+### Other changes ###
+
+This release contains other bug fixes and new features. Among them:
+
+- Annotated descriptions
+
+ Runner UIs, Filters, and Sorters operate on Descriptions of test
+ methods and test classes. These Descriptions now include the
+ annotations on the original Java source element, allowing for richer
+ display of test results, and easier development of annotation-based
+ filters.
+
+- Bug fix (1715326): assertEquals now compares all Numbers using their
+ native implementation of `equals`. This assertion, which passed in
+ 4.3, will now fail:
+
+ assertEquals(new Integer(1), new Long(1));
+
+ Non-integer Numbers (Floats, Doubles, BigDecimals, etc),
+ which were compared incorrectly in 4.3, are now fixed.
+
+- `assertEquals(long, long)` and `assertEquals(double, double)` have
+ been re-introduced to the `Assert` class, to take advantage of
+ Java's native widening conversions. Therefore, this still passes:
+
+ assertEquals(1, 1L);
+
+- The default runner for JUnit 4 test classes has been refactored.
+ The old version was named `TestClassRunner`, and the new is named
+ `JUnit4ClassRunner`. Likewise, `OldTestClassRunner` is now
+ `JUnit3ClassRunner`. The new design allows variations in running
+ individual test classes to be expressed with fewer custom classes.
+ For a good example, see the source to
+ `org.junit.experimental.theories.Theories`.
+
+- The rules for determining which runner is applied by default to a
+ test class have been simplified:
+
+ 1. If the class has a `@RunWith` annotation, the annotated runner
+ class is used.
+
+ 2. If the class can be run with the JUnit 3 test runner (it
+ subclasses `TestCase`, or contains a `public static Test suite()`
+ method), JUnit38ClassRunner is used.
+
+ 3. Otherwise, JUnit4ClassRunner is used.
+
+ This default guess can always be overridden by an explicit
+ `@RunWith(JUnit4ClassRunner.class)` or
+ `@RunWith(JUnit38ClassRunner.class)` annotation.
+
+ The old class names `TestClassRunner` and `OldTestClassRunner`
+ remain as deprecated.
+
+- Bug fix (1739095): Filters and Sorters work correctly on test
+ classes that contain a `suite` method like:
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(MyTest.class);
+ }
+
+- Bug fix (1745048): @After methods are now correctly called
+ after a test method times out.
+
diff --git a/junit4/doc/ReleaseNotes4.5.txt b/junit4/doc/ReleaseNotes4.5.txt
new file mode 100644
index 0000000..66aac70
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.5.txt
@@ -0,0 +1,96 @@
+## Summary of Changes in version 4.5 ##
+
+### Installation ###
+
+- We are releasing `junit-4.5.jar`, which contains all the classes
+ necessary to run JUnit, and `junit-dep-4.5.jar`, which leaves out
+ hamcrest classes, for developers who already use hamcrest outside of
+ JUnit.
+
+### Basic JUnit operation ###
+
+- JUnitCore now more often exits with the correct exit code (0 for
+ success, 1 for failure)
+
+- Badly formed test classes (exceptions in constructors, classes
+ without tests, multiple constructors, Suite without @SuiteClasses)
+ produce more helpful error messages
+
+- Test classes whose only test methods are inherited from superclasses
+ now run.
+
+- Optimization to annotation processing can cut JUnit overhead by more than half
+ on large test classes, especially when using Theories. [Bug 1796847]
+
+- A failing assumption in a constructor ignores the class
+
+- Correct results when comparing the string "null" with potentially
+ null values. [Bug 1857283]
+
+- Annotating a class with `@RunWith(JUnit4.class)` will always invoke the
+ default JUnit 4 runner in the current version of JUnit. This default changed
+ from `JUnit4ClassRunner` in 4.4 to `BlockJUnit4ClassRunner` in 4.5 (see below),
+ and may change again.
+
+### Extension ###
+
+- `BlockJUnit4Runner` is a new implementation of the standard JUnit 4
+ test class functionality. In contrast to `JUnit4ClassRunner` (the old
+ implementation):
+
+ - `BlockJUnit4Runner` has a much simpler implementation based on
+ Statements, allowing new operations to be inserted into the
+ appropriate point in the execution flow.
+
+ - `BlockJUnit4Runner` is published, and extension and reuse are
+ encouraged, whereas `JUnit4ClassRunner` was in an internal package,
+ and is now deprecated.
+
+- `ParentRunner` is a base class for runners that iterate over
+ a list of "children", each an object representing a test or suite to run.
+ `ParentRunner` provides filtering, sorting, `@BeforeClass`, `@AfterClass`,
+ and method validation to subclasses.
+
+- `TestClass` wraps a class to be run, providing efficient, repeated access
+ to all methods with a given annotation.
+
+- The new `RunnerBuilder` API allows extending the behavior of
+ Suite-like custom runners.
+
+- `AssumptionViolatedException.toString()` is more informative
+
+### Extra Runners ###
+
+- `Parameterized.eachOne()` has been removed
+
+- New runner `Enclosed` runs all static inner classes of an outer class.
+
+### Theories ###
+
+- `@Before` and `@After` methods are run before and after each set of attempted parameters
+ on a Theory, and each set of parameters is run on a new instance of the test class.
+
+- Exposed API's `ParameterSignature.getType()` and `ParameterSignature.getAnnotations()`
+
+- An array of data points can be introduced by a field or method
+ marked with the new annotation `@DataPoints`
+
+- The Theories custom runner has been refactored to make it faster and
+ easier to extend
+
+### Development ###
+
+- Source has been split into directories `src/main/java` and
+ `src/test/java`, making it easier to exclude tests from builds, and
+ making JUnit more maven-friendly
+
+- Test classes in `org.junit.tests` have been organized into
+ subpackages, hopefully making finding tests easier.
+
+- `ResultMatchers` has more informative descriptions.
+
+- `TestSystem` allows testing return codes and other system-level interactions.
+
+### Incompatible changes ###
+
+- Removed Request.classes(String, Class<?>...) factory method
diff --git a/junit4/doc/ReleaseNotes4.6.html b/junit4/doc/ReleaseNotes4.6.html
new file mode 100644
index 0000000..36c432a
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.6.html
@@ -0,0 +1,106 @@
+<h2>Summary of Changes in version 4.6</h2>
+
+<h3>Max</h3>
+
+<p>JUnit now includes a new experimental Core, <code>MaxCore</code>. <code>MaxCore</code>
+remembers the results of previous test runs in order to run new
+tests out of order. <code>MaxCore</code> prefers new tests to old tests, fast
+tests to slow tests, and recently failing tests to tests that last
+failed long ago. There's currently not a standard UI for running
+<code>MaxCore</code> included in JUnit, but there is a UI included in the JUnit
+Max Eclipse plug-in at:</p>
+
+<p>http://www.junitmax.com/junitmax/subscribe.html</p>
+
+<p>Example:</p>
+
+<pre><code>public static class TwoUnEqualTests {
+ @Test
+ public void slow() throws InterruptedException {
+ Thread.sleep(100);
+ fail();
+ }
+
+ @Test
+ public void fast() {
+ fail();
+ }
+}
+
+@Test
+public void rememberOldRuns() {
+ File maxFile = new File("history.max");
+ MaxCore firstMax = MaxCore.storedLocally(maxFile);
+ firstMax.run(TwoUnEqualTests.class);
+
+ MaxCore useHistory= MaxCore.storedLocally(maxFile);
+ List&lt;Failure&gt; failures= useHistory.run(TwoUnEqualTests.class)
+ .getFailures();
+ assertEquals("fast", failures.get(0).getDescription().getMethodName());
+ assertEquals("slow", failures.get(1).getDescription().getMethodName());
+}
+</code></pre>
+
+<h3>Test scheduling strategies</h3>
+
+<p><code>JUnitCore</code> now includes an experimental method that allows you to
+specify a model of the <code>Computer</code> that runs your tests. Currently,
+the only built-in Computers are the default, serial runner, and two
+runners provided in the <code>ParallelRunner</code> class:
+<code>ParallelRunner.classes()</code>, which runs classes in parallel, and
+<code>ParallelRunner.methods()</code>, which runs classes and methods in parallel.</p>
+
+<p>This feature is currently less stable than MaxCore, and may be
+merged with MaxCore in some way in the future.</p>
+
+<p>Example:</p>
+
+<pre><code>public static class Example {
+ @Test public void one() throws InterruptedException {
+ Thread.sleep(1000);
+ }
+ @Test public void two() throws InterruptedException {
+ Thread.sleep(1000);
+ }
+}
+
+@Test public void testsRunInParallel() {
+ long start= System.currentTimeMillis();
+ Result result= JUnitCore.runClasses(ParallelComputer.methods(),
+ Example.class);
+ assertTrue(result.wasSuccessful());
+ long end= System.currentTimeMillis();
+ assertThat(end - start, betweenInclusive(1000, 1500));
+}
+</code></pre>
+
+<h3>Comparing double arrays</h3>
+
+<p>Arrays of doubles can be compared, using a delta allowance for equality:</p>
+
+<pre><code>@Test
+public void doubleArraysAreEqual() {
+ assertArrayEquals(new double[] {1.0, 2.0}, new double[] {1.0, 2.0}, 0.01);
+}
+</code></pre>
+
+<h3><code>Filter.matchDescription</code> API</h3>
+
+<p>Since 4.0, it has been possible to run a single method using the <code>Request.method</code>
+API. In 4.6, the filter that implements this is exposed as <code>Filter.matchDescription</code>.</p>
+
+<h3>Documentation</h3>
+
+<ul>
+<li><p>A couple classes and packages that once had empty javadoc have been
+doc'ed.</p></li>
+<li><p>Added how to run JUnit from the command line to the cookbook.</p></li>
+<li><p>junit-4.x.zip now contains build.xml</p></li>
+</ul>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>Fixed overly permissive @DataPoint processing (2191102)</li>
+<li>Fixed bug in test counting after an ignored method (2106324)</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.6.txt b/junit4/doc/ReleaseNotes4.6.txt
new file mode 100644
index 0000000..a5decac
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.6.txt
@@ -0,0 +1,100 @@
+## Summary of Changes in version 4.6 ##
+
+### Max ###
+
+JUnit now includes a new experimental Core, `MaxCore`. `MaxCore`
+remembers the results of previous test runs in order to run new
+tests out of order. `MaxCore` prefers new tests to old tests, fast
+tests to slow tests, and recently failing tests to tests that last
+failed long ago. There's currently not a standard UI for running
+`MaxCore` included in JUnit, but there is a UI included in the JUnit
+Max Eclipse plug-in at:
+
+ http://www.junitmax.com/junitmax/subscribe.html
+
+Example:
+
+ public static class TwoUnEqualTests {
+ @Test
+ public void slow() throws InterruptedException {
+ Thread.sleep(100);
+ fail();
+ }
+
+ @Test
+ public void fast() {
+ fail();
+ }
+ }
+
+ @Test
+ public void rememberOldRuns() {
+ File maxFile = new File("history.max");
+ MaxCore firstMax = MaxCore.storedLocally(maxFile);
+ firstMax.run(TwoUnEqualTests.class);
+
+ MaxCore useHistory= MaxCore.storedLocally(maxFile);
+ List<Failure> failures= useHistory.run(TwoUnEqualTests.class)
+ .getFailures();
+ assertEquals("fast", failures.get(0).getDescription().getMethodName());
+ assertEquals("slow", failures.get(1).getDescription().getMethodName());
+ }
+
+### Test scheduling strategies ###
+
+`JUnitCore` now includes an experimental method that allows you to
+specify a model of the `Computer` that runs your tests. Currently,
+the only built-in Computers are the default, serial runner, and two
+runners provided in the `ParallelRunner` class:
+`ParallelRunner.classes()`, which runs classes in parallel, and
+`ParallelRunner.methods()`, which runs classes and methods in parallel.
+
+This feature is currently less stable than MaxCore, and may be
+merged with MaxCore in some way in the future.
+
+Example:
+
+ public static class Example {
+ @Test public void one() throws InterruptedException {
+ Thread.sleep(1000);
+ }
+ @Test public void two() throws InterruptedException {
+ Thread.sleep(1000);
+ }
+ }
+
+ @Test public void testsRunInParallel() {
+ long start= System.currentTimeMillis();
+ Result result= JUnitCore.runClasses(ParallelComputer.methods(),
+ Example.class);
+ assertTrue(result.wasSuccessful());
+ long end= System.currentTimeMillis();
+ assertThat(end - start, betweenInclusive(1000, 1500));
+ }
+
+### Comparing double arrays ###
+
+Arrays of doubles can be compared, using a delta allowance for equality:
+
+ @Test
+ public void doubleArraysAreEqual() {
+ assertArrayEquals(new double[] {1.0, 2.0}, new double[] {1.0, 2.0}, 0.01);
+ }
+
+### `Filter.matchDescription` API ###
+
+Since 4.0, it has been possible to run a single method using the `Request.method`
+API. In 4.6, the filter that implements this is exposed as `Filter.matchDescription`.
+
+### Documentation ###
+
+- A couple classes and packages that once had empty javadoc have been
+ doc'ed.
+
+- Added how to run JUnit from the command line to the cookbook.
+
+- junit-4.x.zip now contains build.xml
+
+### Bug fixes ###
+- Fixed overly permissive @DataPoint processing (2191102)
+- Fixed bug in test counting after an ignored method (2106324)
diff --git a/junit4/doc/ReleaseNotes4.7.html b/junit4/doc/ReleaseNotes4.7.html
new file mode 100644
index 0000000..69b66c6
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.7.html
@@ -0,0 +1,229 @@
+<h2>Summary of Changes in version 4.7</h2>
+
+<h3>Rules</h3>
+
+<ul>
+<li><p>Rules allow very flexible addition or redefinition of the behavior
+of each test method in a test class. Testers can reuse or extend one of the
+provided Rules below, or write their own.</p>
+
+<p>For more on this feature, see http://www.threeriversinstitute.org/blog/?p=155</p></li>
+<li><p>The TemporaryFolder Rule allows creation of files and folders
+that are guaranteed to be deleted when the test method finishes
+(whether it passes or fails):</p>
+
+<p>public static class HasTempFolder {
+ @Rule
+ public TemporaryFolder folder= new TemporaryFolder();</p>
+
+<pre><code>@Test
+public void testUsingTempFolder() throws IOException {
+ File createdFile= folder.newFile("myfile.txt");
+ File createdFolder= folder.newFolder("subfolder");
+ // ...
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>ExternalResource is a base class for Rules (like TemporaryFolder)
+that set up an external resource before a test (a file, socket, server,
+database connection, etc.), and guarantee to tear it down afterward:</p>
+
+<p>public static class UsesExternalResource {
+ Server myServer = new Server();</p>
+
+<pre><code>@Rule public ExternalResource resource = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ myServer.connect();
+ };
+
+
+<pre><code>@Override
+protected void after() {
+ myServer.disconnect();
+};
+</code></pre>
+
+};
+
+
+@Test public void testFoo() {
+ new Client().run(myServer);
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>The ErrorCollector Rule allows execution of a test to continue
+after the first problem is found (for example, to collect <em>all</em> the
+incorrect rows in a table, and report them all at once):</p>
+
+<p>public static class UsesErrorCollectorTwice {
+ @Rule
+ public ErrorCollector collector= new ErrorCollector();</p>
+
+<pre><code>@Test public void example() {
+ collector.addError(new Throwable("first thing went wrong"));
+ collector.addError(new Throwable("second thing went wrong"));
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>Verifier is a base class for Rules like ErrorCollector, which
+can turn otherwise passing test methods into failing tests if a verification
+check is failed</p>
+
+<p>public static class ErrorLogVerifier() {
+ private ErrorLog errorLog = new ErrorLog();</p>
+
+<p>@Rule
+ public MethodRule verifier = new Verifier() {
+ @Override public void verify() {
+ assertTrue(errorLog.isEmpty());
+ }
+ }</p>
+
+<p>@Test public void testThatMightWriteErrorLog() {
+ // ...
+ }
+}</p></li>
+<li><p>TestWatchman is a base class for Rules that take note
+of the testing action, without modifying it.
+For example, this class will keep a log of each passing and failing
+test:</p>
+
+<p>public static class WatchmanTest {
+ private static String watchedLog;</p>
+
+<pre><code>@Rule
+public MethodRule watchman= new TestWatchman() {
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ watchedLog+= method.getName() + " "
+ + e.getClass().getSimpleName() + "\n";
+ }
+
+
+<pre><code>@Override
+public void succeeded(FrameworkMethod method) {
+ watchedLog+= method.getName() + " " + "success!\n";
+}
+</code></pre>
+
+};
+
+
+@Test
+public void fails() {
+ fail();
+}
+
+
+@Test
+public void succeeds() {
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>The TestName Rule makes the current test name available inside test methods:</p>
+
+<p>public class NameRuleTest {
+ @Rule public TestName name = new TestName();</p>
+
+<pre><code>@Test public void testA() {
+ assertEquals("testA", name.getMethodName());
+}
+
+
+@Test public void testB() {
+ assertEquals("testB", name.getMethodName());
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>The Timeout Rule applies the same timeout to all test methods in a class:</p>
+
+<p>public static class HasGlobalTimeout {
+ public static String log;</p>
+
+<pre><code>@Rule public MethodRule globalTimeout = new Timeout(20);
+
+
+@Test public void testInfiniteLoop1() {
+ log+= "ran1";
+ for(;;) {}
+}
+
+
+@Test public void testInfiniteLoop2() {
+ log+= "ran2";
+ for(;;) {}
+}
+</code></pre>
+
+<p>}</p></li>
+<li><p>The ExpectedException Rule allows in-test specification
+of expected exception types and messages:</p>
+
+<p>public static class HasExpectedException {
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();</p>
+
+<pre><code>@Test
+public void throwsNothing() {
+
+
+}
+
+
+@Test
+public void throwsNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ throw new NullPointerException();
+}
+
+
+@Test
+public void throwsNullPointerExceptionWithMessage() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("happened?");
+ thrown.expectMessage(startsWith("What"));
+ throw new NullPointerException("What happened?");
+}
+</code></pre>
+
+<p>}</p></li>
+</ul>
+
+<h3>Timeouts</h3>
+
+<ul>
+<li>Tests that time out now show the stack trace of the test thread.</li>
+</ul>
+
+<h3>Matchers</h3>
+
+<ul>
+<li>Due to typing incompatibilities, JUnit is still including the 1.1 release
+of hamcrest. This is not a change from 4.6, but is a change from
+pre-beta releases of 4.7. Due to this incompatibility, tests using
+Hamcrest 1.2 must still use the MatcherAssert.assertThat method from
+Hamcrest, not Assert.assertThat from JUnit.</li>
+</ul>
+
+<h3>Docs</h3>
+
+<ul>
+<li>Javadocs now link to online JDK javadocs (bug 2090230)</li>
+<li>Parameterized runner javadocs improved (bug 2186792)</li>
+<li>Fixed Javadoc code sample for AfterClass (2126279)</li>
+<li>Fixed Javadoc for assertArraysEqual(float[], float[])</li>
+</ul>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>Fixed: BaseTestRunner.getTest() requires class to extend TestCase (1812200)</li>
+<li>Fixed: Suite does not allow for inheritance in annotations (2783118)</li>
+<li>Fixed: ParallelComputer skipped tests that took longer than 2 seconds</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.7.txt b/junit4/doc/ReleaseNotes4.7.txt
new file mode 100644
index 0000000..11b70c1
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.7.txt
@@ -0,0 +1,194 @@
+## Summary of Changes in version 4.7 ##
+
+### Rules ###
+
+- Rules allow very flexible addition or redefinition of the behavior
+ of each test method in a test class. Testers can reuse or extend one of the
+ provided Rules below, or write their own.
+
+ For more on this feature, see http://www.threeriversinstitute.org/blog/?p=155
+
+- The TemporaryFolder Rule allows creation of files and folders
+ that are guaranteed to be deleted when the test method finishes
+ (whether it passes or fails):
+
+ public static class HasTempFolder {
+ @Rule
+ public TemporaryFolder folder= new TemporaryFolder();
+
+ @Test
+ public void testUsingTempFolder() throws IOException {
+ File createdFile= folder.newFile("myfile.txt");
+ File createdFolder= folder.newFolder("subfolder");
+ // ...
+ }
+ }
+
+- ExternalResource is a base class for Rules (like TemporaryFolder)
+ that set up an external resource before a test (a file, socket, server,
+ database connection, etc.), and guarantee to tear it down afterward:
+
+ public static class UsesExternalResource {
+ Server myServer = new Server();
+
+ @Rule public ExternalResource resource = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ myServer.connect();
+ };
+
+ @Override
+ protected void after() {
+ myServer.disconnect();
+ };
+ };
+
+ @Test public void testFoo() {
+ new Client().run(myServer);
+ }
+ }
+
+- The ErrorCollector Rule allows execution of a test to continue
+ after the first problem is found (for example, to collect _all_ the
+ incorrect rows in a table, and report them all at once):
+
+ public static class UsesErrorCollectorTwice {
+ @Rule
+ public ErrorCollector collector= new ErrorCollector();
+
+ @Test public void example() {
+ collector.addError(new Throwable("first thing went wrong"));
+ collector.addError(new Throwable("second thing went wrong"));
+ }
+ }
+
+- Verifier is a base class for Rules like ErrorCollector, which
+ can turn otherwise passing test methods into failing tests if a verification
+ check is failed
+
+ public static class ErrorLogVerifier() {
+ private ErrorLog errorLog = new ErrorLog();
+
+ @Rule
+ public MethodRule verifier = new Verifier() {
+ @Override public void verify() {
+ assertTrue(errorLog.isEmpty());
+ }
+ }
+
+ @Test public void testThatMightWriteErrorLog() {
+ // ...
+ }
+ }
+
+- TestWatchman is a base class for Rules that take note
+ of the testing action, without modifying it.
+ For example, this class will keep a log of each passing and failing
+ test:
+
+ public static class WatchmanTest {
+ private static String watchedLog;
+
+ @Rule
+ public MethodRule watchman= new TestWatchman() {
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ watchedLog+= method.getName() + " "
+ + e.getClass().getSimpleName() + "\n";
+ }
+
+ @Override
+ public void succeeded(FrameworkMethod method) {
+ watchedLog+= method.getName() + " " + "success!\n";
+ }
+ };
+
+ @Test
+ public void fails() {
+ fail();
+ }
+
+ @Test
+ public void succeeds() {
+ }
+ }
+
+- The TestName Rule makes the current test name available inside test methods:
+
+ public class NameRuleTest {
+ @Rule public TestName name = new TestName();
+
+ @Test public void testA() {
+ assertEquals("testA", name.getMethodName());
+ }
+
+ @Test public void testB() {
+ assertEquals("testB", name.getMethodName());
+ }
+ }
+
+- The Timeout Rule applies the same timeout to all test methods in a class:
+
+ public static class HasGlobalTimeout {
+ public static String log;
+
+ @Rule public MethodRule globalTimeout = new Timeout(20);
+
+ @Test public void testInfiniteLoop1() {
+ log+= "ran1";
+ for(;;) {}
+ }
+
+ @Test public void testInfiniteLoop2() {
+ log+= "ran2";
+ for(;;) {}
+ }
+ }
+
+- The ExpectedException Rule allows in-test specification
+ of expected exception types and messages:
+
+ public static class HasExpectedException {
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();
+
+ @Test
+ public void throwsNothing() {
+
+ }
+
+ @Test
+ public void throwsNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ throw new NullPointerException();
+ }
+
+ @Test
+ public void throwsNullPointerExceptionWithMessage() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("happened?");
+ thrown.expectMessage(startsWith("What"));
+ throw new NullPointerException("What happened?");
+ }
+ }
+
+### Timeouts ###
+- Tests that time out now show the stack trace of the test thread.
+
+### Matchers ###
+- Due to typing incompatibilities, JUnit is still including the 1.1 release
+ of hamcrest. This is not a change from 4.6, but is a change from
+ pre-beta releases of 4.7. Due to this incompatibility, tests using
+ Hamcrest 1.2 must still use the MatcherAssert.assertThat method from
+ Hamcrest, not Assert.assertThat from JUnit.
+
+### Docs ###
+- Javadocs now link to online JDK javadocs (bug 2090230)
+- Parameterized runner javadocs improved (bug 2186792)
+- Fixed Javadoc code sample for AfterClass (2126279)
+- Fixed Javadoc for assertArraysEqual(float[], float[])
+
+### Bug fixes ###
+- Fixed: BaseTestRunner.getTest() requires class to extend TestCase (1812200)
+- Fixed: Suite does not allow for inheritance in annotations (2783118)
+- Fixed: ParallelComputer skipped tests that took longer than 2 seconds
diff --git a/junit4/doc/ReleaseNotes4.8.1.html b/junit4/doc/ReleaseNotes4.8.1.html
new file mode 100644
index 0000000..32e36a6
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.1.html
@@ -0,0 +1,9 @@
+<h2>Summary of Changes in version 4.8.1</h2>
+
+<p>This was a quick bugfix release for an important bug</p>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>github#61: Category annotations on classes were not honored.</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.8.1.txt b/junit4/doc/ReleaseNotes4.8.1.txt
new file mode 100644
index 0000000..bc13f26
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.1.txt
@@ -0,0 +1,7 @@
+## Summary of Changes in version 4.8.1 ##
+
+This was a quick bugfix release for an important bug
+
+### Bug fixes ###
+
+- github#61: Category annotations on classes were not honored. \ No newline at end of file
diff --git a/junit4/doc/ReleaseNotes4.8.2.html b/junit4/doc/ReleaseNotes4.8.2.html
new file mode 100644
index 0000000..273f03b
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.2.html
@@ -0,0 +1,10 @@
+<h2>Summary of Changes in version 4.8.2</h2>
+
+<p>This was a quick bugfix release</p>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>github#96: TestSuite(MyTestCase.class) should dynamically detect if MyTestCase
+is a TestCase</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.8.2.txt b/junit4/doc/ReleaseNotes4.8.2.txt
new file mode 100644
index 0000000..8631275
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.2.txt
@@ -0,0 +1,8 @@
+## Summary of Changes in version 4.8.2 ##
+
+This was a quick bugfix release
+
+### Bug fixes ###
+
+- github#96: TestSuite(MyTestCase.class) should dynamically detect if MyTestCase
+ is a TestCase
diff --git a/junit4/doc/ReleaseNotes4.8.html b/junit4/doc/ReleaseNotes4.8.html
new file mode 100644
index 0000000..086f5d0
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.html
@@ -0,0 +1,59 @@
+<h2>Summary of Changes in version 4.8</h2>
+
+<h3>Categories</h3>
+
+<p>From a given set of test classes, the <code>Categories</code> runner
+runs only the classes and methods
+that are annotated with either the category given with the <code>@IncludeCategory</code>
+annotation, or a subtype of that category. Either classes or interfaces can be
+used as categories. Subtyping works, so if you say <code>@IncludeCategory(SuperClass.class)</code>,
+a test marked <code>@Category({SubClass.class})</code> will be run.</p>
+
+<p>You can also exclude categories by using the <code>@ExcludeCategory</code> annotation</p>
+
+<p>Example:</p>
+
+<pre><code>public interface FastTests { /* category marker */ }
+public interface SlowTests { /* category marker */ }
+
+public class A {
+ @Test
+ public void a() {
+ fail();
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+ }
+}
+
+@Category({SlowTests.class, FastTests.class})
+public class B {
+ @Test
+ public void c() {
+
+ }
+}
+
+@RunWith(Categories.class)
+@IncludeCategory(SlowTests.class)
+@SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
+public class SlowTestSuite {
+ // Will run A.b and B.c, but not A.a
+}
+
+@RunWith(Categories.class)
+@IncludeCategory(SlowTests.class)
+@ExcludeCategory(FastTests.class)
+@SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
+public class SlowTestSuite {
+ // Will run A.b, but not A.a or B.c
+}
+</code></pre>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>github#16: thread safety of Result counting</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.8.txt b/junit4/doc/ReleaseNotes4.8.txt
new file mode 100644
index 0000000..4a30db6
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.8.txt
@@ -0,0 +1,56 @@
+## Summary of Changes in version 4.8 ##
+
+### Categories ###
+
+From a given set of test classes, the `Categories` runner
+runs only the classes and methods
+that are annotated with either the category given with the `@IncludeCategory`
+annotation, or a subtype of that category. Either classes or interfaces can be
+used as categories. Subtyping works, so if you say `@IncludeCategory(SuperClass.class)`,
+a test marked `@Category({SubClass.class})` will be run.
+
+You can also exclude categories by using the `@ExcludeCategory` annotation
+
+Example:
+
+ public interface FastTests { /* category marker */ }
+ public interface SlowTests { /* category marker */ }
+
+ public class A {
+ @Test
+ public void a() {
+ fail();
+ }
+
+ @Category(SlowTests.class)
+ @Test
+ public void b() {
+ }
+ }
+
+ @Category({SlowTests.class, FastTests.class})
+ public class B {
+ @Test
+ public void c() {
+
+ }
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
+ public class SlowTestSuite {
+ // Will run A.b and B.c, but not A.a
+ }
+
+ @RunWith(Categories.class)
+ @IncludeCategory(SlowTests.class)
+ @ExcludeCategory(FastTests.class)
+ @SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
+ public class SlowTestSuite {
+ // Will run A.b, but not A.a or B.c
+ }
+
+### Bug fixes ###
+
+- github#16: thread safety of Result counting \ No newline at end of file
diff --git a/junit4/doc/ReleaseNotes4.9.1.txt b/junit4/doc/ReleaseNotes4.9.1.txt
new file mode 100644
index 0000000..eded783
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.9.1.txt
@@ -0,0 +1,14 @@
+## Summary of Changes in version 4.9.1 [unreleased!] ##
+
+### Theories ###
+
+The `Theories` runner does not anticipate theory parameters that have generic
+types, as reported by github#64. Fixing this won't happen until `Theories` is
+moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
+necessary machinery to the runner classes, and deprecates a method that only
+the `Theories` runner uses, `FrameworkMethod`#producesType().
+The Common Public License that JUnit is released under is now included
+in the source repository.
+
+Thanks to `@pholser` for identifying a potential resolution for github#64
+and initiating work on it.
diff --git a/junit4/doc/ReleaseNotes4.9.html b/junit4/doc/ReleaseNotes4.9.html
new file mode 100644
index 0000000..3692102
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.9.html
@@ -0,0 +1,96 @@
+<h2>Summary of Changes in version 4.9, final</h2>
+
+<p>Release theme: Test-class and suite level Rules.</p>
+
+<h3>ClassRule</h3>
+
+<p>The <code>ClassRule</code> annotation extends the idea of method-level Rules,
+adding static fields that can affect the operation of a whole class. Any
+subclass of <code>ParentRunner</code>, including the standard <code>BlockJUnit4ClassRunner</code>
+and <code>Suite</code> classes, will support <code>ClassRule</code>s.</p>
+
+<p>For example, here is a test suite that connects to a server once before
+all the test classes run, and disconnects after they are finished:</p>
+
+<pre><code>@RunWith(Suite.class)
+@SuiteClasses({A.class, B.class, C.class})
+public class UsesExternalResource {
+ public static Server myServer= new Server();
+
+ @ClassRule
+ public static ExternalResource resource= new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ myServer.connect();
+ };
+
+ @Override
+ protected void after() {
+ myServer.disconnect();
+ };
+ };
+}
+</code></pre>
+
+<h3>TestRule</h3>
+
+<p>In JUnit 4.9, fields that can be annotated with either <code>@Rule</code> or <code>@ClassRule</code>
+should be of type <code>TestRule</code>. The old <code>MethodRule</code> type, which only made sense
+for method-level rules, will still work, but is deprecated.</p>
+
+<p>Most built-in Rules have been moved to the new type already, in a way that
+should be transparent to most users. <code>TestWatchman</code> has been deprecated,
+and replaced by <code>TestWatcher</code>, which has the same functionality, but implements
+the new type.</p>
+
+<h3>Maven support</h3>
+
+<p>Maven bundles have, in the past, been uploaded by kind volunteers. Starting
+with this release, the JUnit team is attempting to perform this task ourselves.</p>
+
+<h3>LICENSE checked in</h3>
+
+<p>The Common Public License that JUnit is released under is now included
+in the source repository.</p>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>github#98: assumeTrue() does not work with expected exceptions</li>
+<li><p>github#74: Categories + Parameterized</p>
+
+<p>In JUnit 4.8.2, the Categories runner would fail to run correctly
+if any contained test class had a custom Runner with a structure
+significantly different from the built-in Runner. With this fix,
+such classes can be assigned one or more categories at the class level,
+and will be run correctly. Trying to assign categories to methods within
+such a class will flag an error.</p></li>
+<li><p>github#38: ParentRunner filters more than once</p>
+
+<p>Thanks to <code>@reinholdfuereder</code></p></li>
+<li><p>github#248: protected BlockJUnit4ClassRunner#rules method removed from 4.8.2</p></li>
+<li>github#187: Accidental dependency on Java 6</li>
+</ul>
+
+<p>Thanks to <code>@kcooney</code> for:</p>
+
+<ul>
+<li>github#163: Bad comparison failure message when using assertEquals(String, String)</li>
+<li>github#227: ParentRunner now assumes that getChildren() returns a modifiable list</li>
+</ul>
+
+<h3>Minor changes</h3>
+
+<ul>
+<li>Backed out unused folder "experimental-use-of-antunit", replaced by
+bash-based script at build_tests.sh</li>
+<li>Various Javadoc fixes</li>
+</ul>
+
+<p>Thanks to <code>@kcooney</code> for:</p>
+
+<ul>
+<li>Made MultipleFailureException public, to assist extension writers.</li>
+<li>github#240: Add "test" target to build.xml, for faster ant-driven testing.</li>
+<li>github#247: Give InitializationError a useful message</li>
+</ul>
diff --git a/junit4/doc/ReleaseNotes4.9.txt b/junit4/doc/ReleaseNotes4.9.txt
new file mode 100644
index 0000000..8b2a63d
--- /dev/null
+++ b/junit4/doc/ReleaseNotes4.9.txt
@@ -0,0 +1,89 @@
+## Summary of Changes in version 4.9, final ##
+
+Release theme: Test-class and suite level Rules.
+
+### ClassRule ###
+
+The `ClassRule` annotation extends the idea of method-level Rules,
+adding static fields that can affect the operation of a whole class. Any
+subclass of `ParentRunner`, including the standard `BlockJUnit4ClassRunner`
+and `Suite` classes, will support `ClassRule`s.
+
+For example, here is a test suite that connects to a server once before
+all the test classes run, and disconnects after they are finished:
+
+ @RunWith(Suite.class)
+ @SuiteClasses({A.class, B.class, C.class})
+ public class UsesExternalResource {
+ public static Server myServer= new Server();
+
+ @ClassRule
+ public static ExternalResource resource= new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ myServer.connect();
+ };
+
+ @Override
+ protected void after() {
+ myServer.disconnect();
+ };
+ };
+ }
+
+### TestRule ###
+
+In JUnit 4.9, fields that can be annotated with either `@Rule` or `@ClassRule`
+should be of type `TestRule`. The old `MethodRule` type, which only made sense
+for method-level rules, will still work, but is deprecated.
+
+Most built-in Rules have been moved to the new type already, in a way that
+should be transparent to most users. `TestWatchman` has been deprecated,
+and replaced by `TestWatcher`, which has the same functionality, but implements
+the new type.
+
+### Maven support ###
+
+Maven bundles have, in the past, been uploaded by kind volunteers. Starting
+with this release, the JUnit team is attempting to perform this task ourselves.
+
+### LICENSE checked in ###
+
+The Common Public License that JUnit is released under is now included
+in the source repository.
+
+### Bug fixes ###
+
+- github#98: assumeTrue() does not work with expected exceptions
+- github#74: Categories + Parameterized
+
+ In JUnit 4.8.2, the Categories runner would fail to run correctly
+ if any contained test class had a custom Runner with a structure
+ significantly different from the built-in Runner. With this fix,
+ such classes can be assigned one or more categories at the class level,
+ and will be run correctly. Trying to assign categories to methods within
+ such a class will flag an error.
+
+- github#38: ParentRunner filters more than once
+
+ Thanks to `@reinholdfuereder`
+
+- github#248: protected BlockJUnit4ClassRunner#rules method removed from 4.8.2
+- github#187: Accidental dependency on Java 6
+
+Thanks to `@kcooney` for:
+
+- github#163: Bad comparison failure message when using assertEquals(String, String)
+- github#227: ParentRunner now assumes that getChildren() returns a modifiable list
+
+### Minor changes ###
+
+- Backed out unused folder "experimental-use-of-antunit", replaced by
+ bash-based script at build_tests.sh
+- Various Javadoc fixes
+
+Thanks to `@kcooney` for:
+
+- Made MultipleFailureException public, to assist extension writers.
+- github#240: Add "test" target to build.xml, for faster ant-driven testing.
+- github#247: Give InitializationError a useful message
diff --git a/junit4/doc/building-junit.txt b/junit4/doc/building-junit.txt
new file mode 100644
index 0000000..e785b05
--- /dev/null
+++ b/junit4/doc/building-junit.txt
@@ -0,0 +1,19 @@
+Steps to build junit:
+
+- Must be manual
+ - Write release notes
+ - Update version in build.xml
+- Not too tedious:
+ - Push to github (dsaff _and_ KentBeck)
+ - Run the ant zip task
+ - Upload stuff to github (including tag)
+ - Push to maven
+ - ant -lib build/lib stage.maven
+ - Promote
+- Tedious:
+ - Update SourceForge if major release
+ - Update javadocs on github site (and "latest" link)
+ - Update javadocs on junit.org
+ - Put release notes on github.
+ - Announce on blog, user list, dev list, announce list, junit.org, twitter
+- Profit!
diff --git a/junit4/doc/cookbook/cookbook.htm b/junit4/doc/cookbook/cookbook.htm
new file mode 100644
index 0000000..2cf8eec
--- /dev/null
+++ b/junit4/doc/cookbook/cookbook.htm
@@ -0,0 +1,143 @@
+<!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>
diff --git a/junit4/doc/cookbook/logo.gif b/junit4/doc/cookbook/logo.gif
new file mode 100644
index 0000000..d0e1547
--- /dev/null
+++ b/junit4/doc/cookbook/logo.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image1.gif b/junit4/doc/cookstour/Image1.gif
new file mode 100644
index 0000000..398d4cc
--- /dev/null
+++ b/junit4/doc/cookstour/Image1.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image2.gif b/junit4/doc/cookstour/Image2.gif
new file mode 100644
index 0000000..072149f
--- /dev/null
+++ b/junit4/doc/cookstour/Image2.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image3.gif b/junit4/doc/cookstour/Image3.gif
new file mode 100644
index 0000000..dbf6649
--- /dev/null
+++ b/junit4/doc/cookstour/Image3.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image4.gif b/junit4/doc/cookstour/Image4.gif
new file mode 100644
index 0000000..b0b1f2b
--- /dev/null
+++ b/junit4/doc/cookstour/Image4.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image5.gif b/junit4/doc/cookstour/Image5.gif
new file mode 100644
index 0000000..5393c63
--- /dev/null
+++ b/junit4/doc/cookstour/Image5.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image6.gif b/junit4/doc/cookstour/Image6.gif
new file mode 100644
index 0000000..6804925
--- /dev/null
+++ b/junit4/doc/cookstour/Image6.gif
Binary files differ
diff --git a/junit4/doc/cookstour/Image7.gif b/junit4/doc/cookstour/Image7.gif
new file mode 100644
index 0000000..6af54a6
--- /dev/null
+++ b/junit4/doc/cookstour/Image7.gif
Binary files differ
diff --git a/junit4/doc/cookstour/cookstour.htm b/junit4/doc/cookstour/cookstour.htm
new file mode 100644
index 0000000..597dcd8
--- /dev/null
+++ b/junit4/doc/cookstour/cookstour.htm
@@ -0,0 +1,668 @@
+<!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 Word 97">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win95; I) [Netscape]">
+ <meta name="Author" content="ERICH GAMMA">
+ <title>JUnit: A Cook’s Tour</title>
+</head>
+<body>
+
+<h1>
+<font color="#33FF33">J</font><font color="#CC0000">U</font>nit A Cook's
+Tour</h1>
+<br>Note: this article is based on JUnit 3.8.x.
+<hr WIDTH="100%">
+<p><b><font face="Arial"><font size=+1>1. Introduction</font></font></b>
+<p><font size=-1>In an earlier article (see Test Infected: Programmers
+Love Writing Tests, Java Report, July 1998, Volume 3, Number 7), we described
+how to use a simple framework to write repeatable tests. In this article,
+we will take a peek under the covers and show you how the framework itself
+is constructed.</font>
+<p><font size=-1>We carefully studied the JUnit framework and reflected
+on how we constructed it. We found lessons at many different levels. In
+this article we will try communicate them all at once, a hopeless task,
+but at least we will do it in the context of showing you the design and
+construction of a piece of software with proven value.</font>
+<p><font size=-1>We open with a discussion of the goals of the framework.
+The goals will reappear in many small details during the presentation of
+the framework itself. Following this, we present the design and implementation
+of the framework. The design will be described in terms of patterns (surprise,
+surprise), the implementation as a literate program. We conclude with a
+few choice thoughts about framework development.</font>
+<p><b><font face="Arial"><font size=+1>2. Goals</font></font></b>
+<p><font size=-1>What are the goals of JUnit?</font>
+<p><font size=-1>First, we have to get back to the assumptions of development.
+If a program feature lacks an automated test, we assume it doesn’t work.
+This seems much safer than the prevailing assumption, that if a developer
+assures us a program feature works, then it works now and forever.</font>
+<p><font size=-1>From this perspective, developers aren’t done when they
+write and debug the code, they must also write tests that demonstrate that
+the program works. However, everybody is too busy, they have too much to
+do, they don’t have enough time, to screw around with testing. I have too
+much code to write already, how am I supposed write test code, too? Answer
+me that, Mr. Hard-case Project Manager.</font>
+<p><font size=-1>So, the number one goal is to write a framework within
+which we have some glimmer of hope that developers will actually write
+tests. The framework has to use familiar tools, so there is little new
+to learn. It has to require no more work than absolutely necessary to write
+a new test. It has to eliminate duplicated effort.</font>
+<p><font size=-1>If this was all tests had to do, you would be done just
+by writing expressions in a debugger. However, this isn’t sufficient for
+testing. Telling me that your program works now doesn’t help me, because
+it doesn’t assure me that your program will work one minute from now after
+I integrate, and it doesn’t assure me that your program will still work
+in five years, when you are long gone.</font>
+<p><font size=-1>So, the second goal of testing is creating tests that
+retain their value over time. Someone other than the original author has
+to be able to execute the tests and interpret the results. It should be
+possible to combine tests from various authors and run them together without
+fear of interference.</font>
+<p><font size=-1>Finally, it has to be possible to leverage existing tests
+to create new ones. Creating a setup or fixture is expensive and a framework
+has to enable reusing fixtures to run different tests. Oh, is that all?</font>
+<p><b><font face="Arial"><font size=+1>3. The Design of JUnit</font></font></b>
+<p><font size=-1>The design of JUnit will be presented in a style first
+used in (see "Patterns Generate Architectures", Kent Beck and Ralph Johnson,
+ECOOP 94). The idea is to explain the design of a system by starting with
+nothing and applying patterns, one after another, until you have the architecture
+of the system. We will present the architectural problem to be solved,
+summarize the pattern that solves it, and then show how the pattern was
+applied to JUnit.</font>
+<p><b><i><font face="Arial">3.1 Getting started- TestCase</font></i></b>
+<p><font size=-1>First we have to make an object to represent our basic
+concept, the TestCase. Developers often have tests cases in mind, but they
+realize them in many different ways-</font>
+<ul>
+<li>
+<font size=-1>print statements,</font></li>
+
+<li>
+<font size=-1>debugger expressions,</font></li>
+
+<li>
+<font size=-1>test scripts.</font></li>
+</ul>
+<font size=-1>If we want to make manipulating tests easy, we have to make
+them objects. This takes a test that was only implicit in the developer’s
+mind and makes it concrete, supporting our goal of creating tests that
+retain their value over time. At the same time, object developers are used
+to, well, developing with objects, so the decision to make tests into objects
+supports our goal of making test writing more inviting (or at least less
+imposing).</font>
+<p><font size=-1>The Command pattern (see Gamma, E., et al. Design Patterns:
+Elements of Reusable Object-Oriented Software, Addison-Wesley, Reading,
+MA, 1995) fits our needs quite nicely. Quoting from the intent, "Encapsulate
+a request as an object, thereby letting you… queue or log requests…" Command
+tells us to create an object for an operation and give it a method "execute".
+Here is the code for the class definition of TestCase:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public abstract class <b>TestCase</b>
+implements Test {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; …</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>Because we expect this class to be reused through inheritance,
+we declare it "public abstract". For now, ignore the fact that it implements
+the Test interface. For the purposes of our current design, you can think
+of TestCase as a lone class.</font>
+<p><font size=-1>Every TestCase is created with a name, so if a test fails,
+you can identify which test failed.</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public abstract class <b>TestCase</b>
+implements Test {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; private final String
+fName;</font></font>
+<p><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public <b>TestCase</b>(String
+name) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+fName= name;</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<p><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public abstract
+void <b>run</b>();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+…</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>To illustrate the evolution of JUnit, we use diagrams that
+show snapshots of the architecture. The notation we use is simple. It annotates
+classes with shaded boxes containing the associated pattern. When the role
+of the class in the pattern is obvious then only the pattern name is shown.
+If the role isn’t clear then the shaded box is augmented by the name of
+the participant this class corresponds to. This notation minimizes the
+clutter in diagrams and was first shown in (see Gamma, E., Applying Design
+Patterns in Java, in Java Gems, SIGS Reference Library, 1997) Figure 1
+shows this notation applied to TestCase. Since we are dealing with a single
+class and there can be no ambiguities just the pattern name is shown.</font>
+<center>
+<p><img SRC="Image1.gif" height=92 width=238>
+<p><font size=-1><b>Figure 1</b> TestCase applies Command</font></center>
+
+<p><b><i><font face="Arial">3.2 Blanks to fill in- run()</font></i></b>
+<p><font size=-1>The next problem to solve is giving the developer a convenient
+"place" to put their fixture code and their test code. The declaration
+of TestCase as abstract says that the developer is expected to reuse TestCase
+by subclassing. However, if all we could do was provide a superclass with
+one variable and no behavior, we wouldn’t be doing much to satisfy our
+first goal, making tests easier to write.</font>
+<p><font size=-1>Fortunately, there is a common structure to all tests-
+they set up a test fixture, run some code against the fixture, check some
+results, and then clean up the fixture. This means that each test will
+run with a fresh fixture and the results of one test can’t influence the
+result of another. This supports the goal of maximizing the value of the
+tests.</font>
+<p><font size=-1>Template Method addresses our problem quite nicely. Quoting
+from the intent, "Define the skeleton of an algorithm in an operation,
+deferring some steps to subclasses. Template Method lets subclasses redefine
+certain steps of an algorithm without changing the algorithm’s structure."
+This is exactly right. We want the developer to be able to separately consider
+how to write the fixture (set up and tear down) code and how to write the
+testing code. The execution of this sequence, however, will remain the
+same for all tests, no matter how the fixture code is written or how the
+testing code is written.</font>
+<p><font size=-1>Here is the template method:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>run</b>() {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; setUp();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; runTest();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; tearDown();</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The default implementations of these methods do nothing:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>protected void <b>runTest</b>() {</font></font>
+<br><font face="Arial"><font size=-2>}</font></font>
+<p><font face="Arial"><font size=-2>protected void <b>setUp</b>() {</font></font>
+<br><font face="Arial"><font size=-2>}</font></font>
+<p><font face="Arial"><font size=-2>protected void <b>tearDown</b>() {</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>Since setUp and tearDown are intended to be overridden but
+will be called by the framework we declare them as protected. The second
+snapshot of our tour is depicted in Figure 2.</font>
+<center>
+<p><img SRC="Image2.gif" height=142 width=270>
+<p><font size=-1><b>Figure 2</b> TestCase.run() applies Template Method</font></center>
+
+<p><b><i><font face="Arial">3.3 Reporting results- TestResult</font></i></b>
+<p><font size=-1>If a TestCase runs in a forest, does anyone care about
+the result? Sure- you run tests to make sure they run. After the test has
+run, you want a record, a summary of what did and didn’t work.</font>
+<p><font size=-1>If tests had equal chances of succeeding or failing, or
+if we only ever ran one test, we could just set a flag in the TestCase
+object and go look at the flag when the test completed. However, tests
+are (intended to be) highly asymmetric- they usually work. Therefore, we
+only want to record the failures and a highly condensed summary of the
+successes.</font>
+<p><font size=-1>The Smalltalk Best Practice Patterns (see Beck, K. Smalltalk
+Best Practice Patterns, Prentice Hall, 1996) has a pattern that is applicable.
+It is called <i>Collecting Parameter</i>. It suggests that when you need
+to collect results over several methods, you should add a parameter to
+the method and pass an object that will collect the results for you. We
+create a new object, TestResult, to collect the results of running tests.</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public class <b>TestResult</b> extends
+Object {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; protected int fRunTests;</font></font>
+<p><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public <b>TestResult</b>()
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+fRunTests= 0;</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>This simple version of TestResult only counts the number
+of tests run. To use it, we have to add a parameter to the TestCase.run()
+method and notify the TestResult that the test is running:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>run</b>(TestResult
+result) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; result.startTest(this);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; setUp();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; runTest();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; tearDown();</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>And the TestResult has to keep track of the number of tests
+run:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public synchronized void <b>startTest</b>(Test
+test) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; fRunTests++;</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>We declare the TestResult method startTest as synchronized
+so that a single TestResult can collect the results safely when the tests
+are run in different threads. Finally, we want to retain the simple external
+interface of TestCase, so we create a no-parameter version of run() that
+creates its own TestResult:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public TestResult <b>run</b>() {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; TestResult result=
+createResult();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; run(result);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; return result;</font></font>
+<br><font face="Arial"><font size=-2>}</font></font>
+<p><font face="Arial"><font size=-2>protected TestResult <b>createResult</b>()
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; return new TestResult();</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>Figure 3 shows our next design snapshot.</font>
+<center>
+<p><img SRC="Image3.gif" height=149 width=325>
+<p><font size=-1>Figure 3: TestResult applies Collecting Parameter</font></center>
+
+<p><font size=-1>If tests always ran correctly, then we wouldn’t have to
+write them. Tests are interesting when they fail, especially if we didn’t
+expect them to fail. What’s more, tests can fail in ways that we expect,
+for example by computing an incorrect result, or they can fail in more
+spectacular ways, for example by writing outside the bounds of an array.
+No matter how the test fails we want to execute the following tests.</font>
+<p><font size=-1>JUnit distinguishes between <i>failures</i> and <i>errors</i>.
+The possibility of a failure is anticipated and checked for with assertions.
+Errors are unanticipated problems like an ArrayIndexOutOfBoundsException.
+Failures are signaled with an AssertionFailedError error. To distinguish
+an unanticipated error from a failure, failures are caught in an extra
+catch clause (1). The second clause (2) catches all other exceptions and
+ensures that our test run continues..</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>run</b>(TestResult
+result) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; result.startTest(this);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; setUp();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; try {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+runTest();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; catch (AssertionFailedError
+e) { //1</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+result.addFailure(this, e);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<p><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; catch (Throwable
+e) { // 2</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+result.addError(this, e);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; finally {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+tearDown();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>An AssertionFailedError is triggered by the assert methods
+provided by TestCase. JUnit provides a set of assert methods for different
+purposes. Here is the simplest one:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>protected void <b>assertTrue</b>(boolean
+condition) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; if (!condition)</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+throw new AssertionFailedError();</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The AssertionFailedError is not meant to be caught by the
+client (a testing method inside a TestCase) but inside the Template Method
+TestCase.run(). We therefore derive AssertionFailedError from Error.</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public class <b>AssertionFailedError</b>
+extends Error {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public AssertionFailedError
+() {}</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The methods to collect the errors in TestResult are shown
+below:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public synchronized void <b>addError</b>(Test
+test, Throwable t) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; fErrors.addElement(new
+TestFailure(test, t));</font></font>
+<br><font face="Arial"><font size=-2>}</font></font>
+<p><font face="Arial"><font size=-2>public synchronized void <b>addFailure</b>(Test
+test, Throwable t) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; fFailures.addElement(new
+TestFailure(test, t));</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>TestFailure is a little framework internal helper class to
+bind together the failed test and the signaled exception for later reporting.</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public class <b>TestFailure</b> extends
+Object {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; protected Test
+fFailedTest;</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; protected Throwable
+fThrownException;</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The canonical form of collecting parameter requires us to
+pass the collecting parameter to each method. If we followed this advice,
+each of the testing methods would require a parameter for the TestResult.
+This results in a "pollution" of these method signatures. As a benevolent
+side effect of using exceptions to signal failures we can avoid this signature
+pollution. A test case method, or a helper method called from it, can throw
+an exception without having to know about the TestResult. As a refresher
+here is a sample test method from our MoneyTest suite. It illustrates how
+a testing method doesn’t have to know anything about a TestResult:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>testMoneyEquals</b>()
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; assertTrue(!f12CHF.equals(null));</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; assertEquals(f12CHF,
+f12CHF);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; assertEquals(f12CHF,
+new Money(12, "CHF"));</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; assertTrue(!f12CHF.equals(f14CHF));</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>JUnit comes with different implementations of TestResult.
+The default implementation counts the number of failures and errors and
+collects the results. TextTestResult collects the results and presents
+them in a textual form. Finally, UITestResult is used by the graphical
+version of the JUnit Test Runner to update the graphical test status.</font>
+<p><font size=-1>TestResult is an extension point of the framework. Clients
+can define their own custom TestResult classes, for example, an HTMLTestResult
+reports the results as an HTML document.</font>
+<p><b><i><font face="Arial">3.4 No stupid subclasses - TestCase again</font></i></b>
+<p><font size=-1>We have applied Command to represent a test. Command relies
+on a single method like execute() (called run() in TestCase) to invoke
+it. This simple interface allows us to invoke different implementations
+of a command through the same interface.</font>
+<p><font size=-1>We need an interface to generically run our tests. However,
+all test cases are implemented as different methods in the same class.
+This avoids the unnecessary proliferation of classes. A given test case
+class may implement many different methods, each defining a single test
+case. Each test case has a descriptive name like testMoneyEquals or testMoneyAdd.
+The test cases don’t conform to a simple command interface. Different instances
+of the same Command class need to be invoked with different methods. Therefore
+our next problem is make all the test cases look the same from the point
+of view of the invoker of the test.</font>
+<p><font size=-1>Reviewing the problems addressed by available design patterns,
+the Adapter pattern springs to mind. Adapter has the following intent "Convert
+the interface of a class into another interface clients expect". This sounds
+like a good match. Adapter tells us different ways to do this. One of them
+is a class adapter, which uses subclassing to adapt the interface. For
+example, to adapt testMoneyEquals to runTest we implement a subclass of
+MoneyTest and override runTest to invoke testMoneyEquals.</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public class <b>TestMoneyEquals</b>
+extends MoneyTest {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public TestMoneyEquals()
+{ super("testMoneyEquals"); }</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; protected void
+runTest () { testMoneyEquals(); }</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The use of subclassing requires us to implement a subclass
+for each test case. This puts an additional burden on the tester. This
+is against the JUnit goal that the framework should make it as simple as
+possible to add a test case. In addition, creating a subclass for each
+testing method results in class bloat. Many classes with only a single
+method are not worth their costs and it will be difficult to come up with
+meaningful names.</font>
+<p><font size=-1>Java provides anonymous inner classes which provide an
+interesting Java-specific solution to the class naming problem. With anonymous
+inner classes we can create an Adapter without having to invent a class
+name:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>TestCase test= new MoneyTest("testMoneyEquals
+") {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; protected void
+runTest() { testMoneyEquals(); }</font></font>
+<br><font face="Arial"><font size=-2>};</font></font></dir>
+</dir>
+<font size=-1>This is much more convenient than full subclassing. It preserves
+compile-time type checking at the cost of some burden on the developer.
+Smalltalk Best Practice Patterns describes another solution for the problem
+of different instances behaving differently under the common heading of<i>
+pluggable behavior</i>. The idea is to use a single class which can be
+parameterized to perform different logic without requiring subclassing.</font>
+<p><font size=-1>The simplest form of pluggable behavior is the <i>Pluggable
+Selector</i>. Pluggable Selector stores a Smalltalk method selector in
+an instance variable. This idea is not limited to Smalltalk. It is also
+applicable to Java. In Java there is no notion of a method selector. However,
+the Java reflection API allows us to invoke a method from a string representing
+the method’s name. We can use this feature to implement a pluggable selector
+in Java. As an aside, we usually don’t use reflection in ordinary application
+code. In our case we are dealing with an infrastructure framework and it
+is therefore OK to wear the reflection hat.</font>
+<p><font size=-1>JUnit offers the client the choice of using pluggable
+selector or implementing an anonymous adapter class as shown above. To
+do so, we provide the pluggable selector as the default implementation
+of the runTest method. In this case the name of the test case has to correspond
+to the name of a test method. We use reflection to invoke the method as
+shown below. First we look up the Method object. Once we have the method
+object we can invoke it and pass its arguments. Since our test methods
+take no arguments we can pass an empty argument array:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>protected void <b>runTest</b>() throws
+Throwable {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; Method runMethod=
+null;</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; try {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+runMethod= getClass().getMethod(fName, new Class[0]);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; } catch (NoSuchMethodException
+e) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+assertTrue("Method \""+fName+"\" not found", false);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; try {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+runMethod.invoke(this, new Class[0]);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; // catch InvocationTargetException
+and IllegalAccessException</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The JDK 1.1 reflection API only allows us to find public
+methods. For this reason you have to declare the test methods as public,
+otherwise you will get a NoSuchMethodException.</font>
+<p><font size=-1>Here is the next design snapshot, with Adapter and Pluggable
+Selector added.</font>
+<center>
+<p><img SRC="Image4.gif" height=271 width=278>
+<p><font size=-1>Figure 4: TestCase applies either Adapter with an anonymous
+inner class or Pluggable Selector</font></center>
+
+<p><b><i><font face="Arial">3.5 Don’t care about one or many - TestSuite</font></i></b>
+<p><font size=-1>To get confidence in the state of a system we need to
+run many tests. Up to this point JUnit can run a single test case and report
+the result in a TestResult. Our next challenge is to extend it so that
+it can run many different tests. This problem can be solved easily when
+the invoker of the tests doesn’t have to care about whether it runs one
+or many test cases. A popular pattern to pull out in such a situation is
+Composite. To quote its intent "Compose objects into tree structures to
+represent part-whole hierarchies. Composite lets clients treat individual
+objects and compositions of objects uniformly." The point about part-whole
+hierarchies is of interest here. We want to support suites of suites of
+suites of tests.</font>
+<p><font size=-1>Composite introduces the following participants:</font>
+<ul>
+<li>
+<font size=-1>Component: declares the interface we want to use to interact
+with our tests.</font></li>
+
+<li>
+<font size=-1>Composite: implements this interface and maintains a collection
+of tests.</font></li>
+
+<li>
+<font size=-1>Leaf: represents a test case in a composition that conforms
+to the Component interface.</font></li>
+</ul>
+<font size=-1>The pattern tells us to introduce an abstract class which
+defines the common interface for single and composite objects. The primary
+purpose of the class is to define an interface. When applying Composite
+in Java we prefer to define an interface and not an abstract class. Using
+an interface avoids committing JUnit to a specific base class for tests.
+All that is required is that the tests conform to this interface. We therefore
+tweak the pattern description and introduce a Test interface:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public interface <b>Test</b> {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; public abstract
+void run(TestResult result);</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>TestCase corresponds to a Leaf in Composite and implements
+this interface as we have seen above.</font>
+<p><font size=-1>Next, we introduce the Composite participant. We name
+the class TestSuite. A TestSuite keeps its child tests in a Vector:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public class <b>TestSuite</b> implements
+<b>Test</b>
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; private Vector
+fTests= new Vector();</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The run() method delegates to its children:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>run</b>(TestResult
+result) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; for (Enumeration
+e= fTests.elements(); e.hasMoreElements(); ) {</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Test test= (Test)e.nextElement();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+test.run(result);</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; }</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+
+<center><img SRC="Image5.gif" height=241 width=562>
+<p><font size=-1>Figure 5: TestSuite applies Composite</font></center>
+
+<p><font size=-1>Finally, clients have to be able to add tests to a suite,
+they can do so with the method addTest:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public void <b>addTest</b>(Test test)
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; fTests.addElement(test);</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>Notice how all of the above code only depends on the Test
+interface. Since both TestCase and TestSuite conform to the Test interface
+we can recursively compose suites of test suites. All developers can create
+their own TestSuites. We can run them all by creating a TestSuite composed
+of those suites.</font>
+<p><font size=-1>Here is an example of creating a TestSuite:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public static Test <b>suite</b>()
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; TestSuite suite=
+new TestSuite();</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; suite.addTest(new
+MoneyTest("testMoneyEquals"));</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; suite.addTest(new
+MoneyTest("testSimpleAdd"));</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>This works fine, but it requires us to add all the tests
+to a suite manually. Early adopters of JUnit told us this was stupid. Whenever
+you write a new test case you have to remember to add it to a static suite()
+method, otherwise it will not be run. We added a convenience constructor
+to TestSuite which takes the test case class as an argument. Its purpose
+is to extract the test methods and create a suite containing them. The
+test methods must follow the simple convention that they start with the
+prefix "test" and take no arguments. The convenience constructor uses this
+convention, constructing the test objects by using reflection to find the
+testing methods. Using this constructor the above code is simplified to:</font>
+<dir>
+<dir><font face="Arial"><font size=-2>public static Test <b>suite</b>()
+{</font></font>
+<br><font face="Arial"><font size=-2>&nbsp;&nbsp;&nbsp; return new TestSuite(MoneyTest.class);</font></font>
+<br><font face="Arial"><font size=-2>}</font></font></dir>
+</dir>
+<font size=-1>The original way is still useful when you want to run a subset
+of the test cases only.</font>
+<p><b><i><font face="Arial">3.6 Summary</font></i></b>
+<p><font size=-1>We are at the end of our cook’s tour through JUnit. The
+following figure shows the design of JUnit at a glance explained with patterns.</font>
+<center>
+<p><img SRC="Image6.gif" height=394 width=605>
+<p><font size=-1>Figure 6: JUnit Patterns Summary</font></center>
+
+<p><font size=-1>Notice how TestCase, the central abstraction in the framework,
+is involved in four patterns. Pictures of mature object designs show this
+same "pattern density". The star of the design has a rich set of relationships
+with the supporting players.</font>
+<p><font size=-1>Here is another way of looking at all of the patterns
+in JUnit. In this storyboard you see an abstract representation of the
+effect of each of the patterns in turn. So, the Command pattern creates
+the TestCase class, the Template Method pattern creates the run method,
+and so on. (The notation of the storyboard is the notation of figure 6
+with all the text deleted).</font>
+<center>
+<p><img SRC="Image7.gif" height=231 width=792>
+<p><font size=-1>Figure 7: JUnit Pattern Storyboard</font></center>
+
+<p><font size=-1>One point to notice about the storyboard is how the complexity
+of the picture jumps when we apply Composite. This is pictorial corroboration
+for our intuition that Composite is a powerful pattern, but that it "complicates
+the picture." It should therefore be used with caution.</font>
+<p><b><font face="Arial"><font size=+1>4. Conclusion</font></font></b>
+<p><font size=-1>To conclude, let’s make some general observations:</font>
+<ul>
+<li>
+<i><font size=-1>Patterns</font></i></li>
+
+<br><font size=-1>We found discussing the design in terms of patterns to
+be invaluable, both as we were developing the framework and as we try to
+explain it to others. You are now in a perfect position to judge whether
+describing a framework with patterns is effective. If you liked the discussion
+above, try the same style of presentation for your own system.</font>
+<li>
+<i><font size=-1>Pattern density</font></i></li>
+
+<br><font size=-1>There is a high pattern "density" around TestCase, which
+is the key abstraction of JUnit. Designs with high pattern density are
+easier to use but harder to change. We have found that such a high pattern
+density around key abstractions is common for mature frameworks. The opposite
+should be true of immature frameworks - they should have low pattern density.
+Once you discover what problem you are really solving, then you can begin
+to "compress" the solution, leading to a denser and denser field of patterns
+where they provide leverage.</font>
+<li>
+<i><font size=-1>Eat your own dog food</font></i></li>
+
+<br><font size=-1>As soon as we had the base unit testing functionality
+implemented, we applied it ourselves. A TestTest verifies that the framework
+reports the correct results for errors, successes, and failures. We found
+this invaluable as we continued to evolve the design of the framework.
+We found that the most challenging application of JUnit was testing its
+own behavior.</font>
+<li>
+<i><font size=-1>Intersection, not union</font></i></li>
+
+<br><font size=-1>There is a temptation in framework development to include
+every feature you can. After all, you want to make the framework as valuable
+as possible. However, there is a counteracting force- developers have to
+decide to use your framework. The fewer features the framework has, the
+easier it is to learn, the more likely a developer will use it. JUnit is
+written in this style. It implements only those features absolutely essential
+to running tests- running suites of tests, isolating the execution of tests
+from each other, and running tests automatically. Sure, we couldn’t resist
+adding some features but we were careful to put them into their own extensions
+package (test.extensions). A notable member of this package is a TestDecorator
+allowing execution of additional code before and after a test.</font>
+<li>
+<i><font size=-1>Framework writers read their code</font></i></li>
+
+<br><font size=-1>We spent far more time reading the JUnit code than we
+spent writing it, and nearly as much time removing duplicate functionality
+as we spent adding new functionality. We experimented aggressively with
+the design, adding new classes and moving responsibility around in as many
+different ways as we could imagine. We were rewarded (and are still being
+rewarded) for our monomania by a continuous flow of insights into JUnit,
+testing, object design, framework development, and opportunities for further
+articles.</font></ul>
+<font size=-1>The latest version of JUnit can be downloaded from http://www.junit.org.</font>
+<p><b><font face="Arial"><font size=+1>5. Acknowledgements</font></font></b>
+<p><font size=-1>Thanks to John Vlissides, Ralph Johnson, and Nick Edgar
+for careful reading and gentle correction.</font>
+</body>
+</html>
diff --git a/junit4/doc/faq/faq.htm b/junit4/doc/faq/faq.htm
new file mode 100644
index 0000000..783557e
--- /dev/null
+++ b/junit4/doc/faq/faq.htm
@@ -0,0 +1,2380 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+ <title>JUnit FAQ</title>
+
+ <style type="text/css">
+
+ body {
+ font-style: normal;
+ font-weight: normal;
+ margin-left: 10pt;
+ margin-right: 10pt;
+ }
+
+ a {
+ text-decoration: none;
+ }
+
+ a:hover {
+ text-decoration: underline;
+ }
+
+ .header {
+ color: black;
+ font-size: 125%;
+ font-weight: bold;
+ background: #33ff33;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ padding-left: 5px;
+ margin-top: 25px;
+ }
+
+ .code {
+ background: white;
+ border-left: 5px solid #33ff33;
+ }
+
+ .code-red {
+ background: white;
+ border-left: 5px solid #cc0000;
+ }
+
+ </style>
+
+</head>
+
+<body>
+
+<h1>
+ <font color="#33ff33">J</font><font color="#cc0000">U</font>nit FAQ
+</h1>
+<hr size="1"/>
+
+
+<!--
+
+ Summary
+
+-->
+<p>
+<i>
+JUnit is a simple, open source framework to write and run repeatable
+tests. It is an instance of the xUnit architecture for unit testing
+frameworks.
+</i>
+</p>
+<hr size="1"/>
+<p>
+Edited by <a href="mailto:mike@clarkware.com">Mike Clark</a>
+(<a href="http://www.clarkware.com">http://clarkware.com</a>)
+</p>
+<p>
+Last modified on February 20, 2006
+</p>
+
+<hr/>
+
+<!--
+
+ Table of Contents
+
+-->
+
+<div class="header">
+Table of Contents
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a href="#faqinfo">FAQ Info</a></b>
+ </p>
+ <ol>
+ <li><a href="#faqinfo_1">Who is responsible for this FAQ?</a></li>
+ <li><a href="#faqinfo_2">How can I contribute to this FAQ?</a></li>
+ <li><a href="#faqinfo_3">Where do I get the latest version of
+ this FAQ?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#overview">Overview</a></b>
+ </p>
+ <ol>
+ <li><a href="#overview_1">What is JUnit?</a></li>
+ <li><a href="#overview_2">Where is the JUnit home page?</a></li>
+ <li><a href="#overview_3">Where are the JUnit mailing lists and
+ forums?</a></li>
+ <li><a href="#overview_4">Where is the JUnit documentation?</a></li>
+ <li><a href="#overview_5">Where can I find articles on JUnit?</a></li>
+ <li><a href="#overview_6">What's the latest news on JUnit?</a></li>
+ <li><a href="#overview_7">How is JUnit licensed?</a></li>
+ <li><a href="#overview_8">What awards has JUnit won?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#started">Getting Started</a></b>
+ </p>
+ <ol>
+ <li><a href="#started_1">Where do I download JUnit?</a></li>
+ <li><a href="#started_2">How do I install JUnit?</a></li>
+ <li><a href="#started_3">How do I uninstall JUnit?</a></li>
+ <li><a href="#started_4">How do I ask questions?</a></li>
+ <li><a href="#started_5">How do I submit bugs, patches, or
+ feature requests?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#tests">Writing Tests</a></b>
+ </p>
+ <ol>
+ <li><a href="#tests_1">How do I write and run a simple test?</a></li>
+ <li><a href="#tests_2">How do I use a test fixture?</a></li>
+ <li><a href="#tests_4">How do I test a method that doesn't
+ return anything?</a></li>
+ <li><a href="#tests_5">Under what conditions should I test get()
+ and set() methods?</a></li>
+ <li><a href="#tests_6">Under what conditions should I not test
+ get() and set() methods?</a></li>
+ <li><a href="#tests_7">How do I write a test that passes when an
+ expected exception is thrown?</a></li>
+ <li><a href="#tests_8">How do I write a test that fails when an
+ unexpected exception is thrown?</a></li>
+ <li><a href="#tests_10">How do I test protected methods?</a></li>
+ <li><a href="#tests_11">How do I test private methods?</a></li>
+ <li><a href="#tests_12">Why does JUnit only report the first
+ failure in a single test?</a></li>
+ <li><a href="#tests_13">In Java 1.4, 'assert' is a
+ keyword. Won't this conflict with JUnit's assert()
+ method?</a></li>
+ <li><a href="#tests_14">How do I test things that must be run in
+ a J2EE container (e.g. servlets, EJBs)?</a></li>
+ <li><a href="#tests_15">Do I need to write a test class for
+ every class I need to test?</a></li>
+ <li><a href="#tests_16">Is there a basic template I can use to
+ create a test?</a></li>
+ <li><a href="#tests_17">How do I write a test for an abstract
+ class?</a></li>
+ <li><a href="#tests_18">When are tests garbage collected?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#organize">Organizing Tests</a></b>
+ </p>
+ <ol>
+ <li><a href="#organize_1">Where should I put my test files?</a></li>
+ <li><a href="#organize_3">How can I run setUp() and tearDown()
+ code once for all of my tests?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#running">Running Tests</a></b>
+ </p>
+ <ol>
+ <li><a href="#running_1">What CLASSPATH settings are needed to
+ run JUnit?</a></li>
+ <li><a href="#running_2">Why do I get a NoClassDefFoundError
+ when trying to test JUnit or run the samples?</a>
+ </li>
+ <li><a href="#running_4">How do I run JUnit from my command window?</a>
+ </li>
+ <li><a href="#running_5">How do I run JUnit using Ant?</a>
+ </li>
+ <li><a href="#running_6">How do I use Ant to create HTML test reports?</a>
+ </li>
+ <li><a href="#running_7">How do I pass command-line arguments to a test execution?</a>
+ </li>
+ <li><a href="#running_9">Why do I get a LinkageError when using
+ XML interfaces in my test class?</a>
+ </li>
+ <li><a href="#running_11">Why do I get the warning "AssertionFailedError: No
+ tests found in XXX" when I run my test?</a>
+ </li>
+ <li><a href="#running_12">Why do I see "Unknown Source" in the stack trace of
+ a test failure, rather than the source file's line number?</a>
+ </li>
+ <li><a href="#running_15">How do I organize all test classes in a TestSuite
+ automatically and not use or manage a TestSuite explicitly?</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#best">Best Practices</a></b>
+ </p>
+ <ol>
+ <li><a href="#best_1">When should tests be written?</a></li>
+ <li><a href="#best_2">Do I have to write a test for
+ everything?</a></li>
+ <li><a href="#best_3">How simple is 'too simple to break'?</a></li>
+ <li><a href="#best_4">How often should I run my tests?</a></li>
+ <li><a href="#best_5">What do I do when a defect is reported?</a></li>
+ <li><a href="#best_6">Why not just use System.out.println()?</a></li>
+ <li><a href="#best_7">Why not just use a debugger?</a></li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a href="#misc">Miscellaneous</a></b>
+ </p>
+ <ol>
+ <li><a href="#misc_1">How do I integrate JUnit with my IDE?</a></li>
+ <li><a href="#misc_2">How do I launch a debugger when a test
+ fails?</a></li>
+ <li><a href="#misc_3">Where can I find unit testing frameworks
+ similar to JUnit for other languages?</a></li>
+ </ol>
+ </li>
+ </ol>
+
+<!--
+
+ FAQ Info
+
+-->
+<div class="header">
+<a name="faqinfo">FAQ Info</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="faqinfo_1">Who is responsible for this FAQ?</a></b>
+ </p>
+ <p>
+ The current version of this FAQ is maintained
+ by <a href="mailto:mike@clarkware.com">Mike Clark</a>.
+ </p>
+ <p>
+ Most of the wisdom contained in this FAQ comes from the
+ collective insights and hard-won experiences of the many good
+ folks who participate on the JUnit mailing list and the JUnit
+ community at large.
+ </p>
+ <p>
+ If you see your genius represented anywhere in this FAQ without
+ due credit to you, please send me an email and I'll make things
+ right.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="faqinfo_2">How can I contribute to this FAQ?</a></b>
+ </p>
+ <p>
+ Your contributions to this FAQ are greatly appreciated! The
+ JUnit community thanks you in advance.
+ </p>
+ <p>
+ To contribute to this FAQ, simply write a JUnit-related question
+ and answer, then send the unformatted text
+ to <a href="mailto:mike@clarkware.com">Mike Clark</a>.
+ Corrections to this FAQ are always appreciated, as well.
+ </p>
+ <p>
+ No reasonable contribution will be denied. Your name will
+ always appear along with any contribution you make.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="faqinfo_3">Where do I get the latest version of this
+ FAQ?</a></b>
+ </p>
+ <p>
+ The master copy of this FAQ is available
+ at <a
+ href="http://junit.sourceforge.net/doc/faq/faq.htm">http://junit.sourceforge.net/doc/faq/faq.htm</a>.
+ </p>
+ <p>
+ The JUnit distribution also includes this FAQ in
+ the <code>doc</code> directory.
+ </p>
+ </li>
+
+</ol>
+
+
+<!--
+
+ Overview
+
+-->
+<div class="header">
+<a name="overview">Overview</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="overview_1">What is JUnit?</a></b>
+ </p>
+ <p>
+ JUnit is a simple, open source framework to write and run
+ repeatable tests. It is an instance of the xUnit architecture
+ for unit testing frameworks. JUnit features include:
+ </p>
+ <ul>
+ <li>Assertions for testing expected results</li>
+ <li>Test fixtures for sharing common test data</li>
+ <li>Test runners for running tests</li>
+ </ul>
+ <p>
+ JUnit was originally written by Erich Gamma and Kent Beck.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_2">Where is the JUnit home page?</a></b>
+ </p>
+ <p>
+ The official JUnit home page is <a
+ href="http://junit.org">http://junit.org</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_3">Where are the JUnit mailing lists and
+ forums?</a></b>
+ </p>
+ <p>
+ There are 3 mailing lists dedicated to everything JUnit:
+ </p>
+ <ul>
+ <li>
+ <a href="http://groups.yahoo.com/group/junit/">JUnit user
+ list</a>. (Search it for answers to frequently asked
+ questions not included here.)
+ </li>
+ <li>
+ <a
+ href="http://lists.sourceforge.net/lists/listinfo/junit-announce">JUnit
+ announcements</a>
+ </li>
+ <li>
+ <a
+ href="http://lists.sourceforge.net/lists/listinfo/junit-devel">JUnit
+ developer list</a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_4">Where is the JUnit
+ documentation?</a></b>
+ </p>
+ <p>
+ The following documents are included in the JUnit distribution
+ in the <code>doc</code> directory:
+ </p>
+ <ul>
+ <li>
+ <a
+ href="http://junit.sourceforge.net/doc/testinfected/testing.htm">JUnit
+ Test Infected: Programmers Love Writing Tests</a>
+ </li>
+ <li>
+ <a
+ href="http://junit.sourceforge.net/doc/cookbook/cookbook.htm">JUnit
+ Cookbook</a>
+ </li>
+ <li>
+ <a
+ href="http://junit.sourceforge.net/doc/cookstour/cookstour.htm">JUnit
+ - A Cook's Tour</a>
+ </li>
+ <li>
+ <a href="http://junit.sourceforge.net/doc/faq/faq.htm">JUnit
+ FAQ</a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_5">Where can I find articles on
+ JUnit?</a></b>
+ </p>
+ <p>
+ The JUnit home page maintains a list
+ of <a href="http://www.junit.org/news/article/index.htm">JUnit
+ articles</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_6">What's the latest news on JUnit?</a></b>
+ </p>
+ <p>
+ The JUnit home page publishes
+ the <a href="http://www.junit.org/news/index.htm">latest JUnit
+ news</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_7">How is JUnit licensed?</a></b>
+ </p>
+ <p>
+ JUnit is <a href="http://www.opensource.org/">Open Source
+ Software</a>, released
+ under <a
+ href="http://oss.software.ibm.com/developerworks/oss/license-cpl.html">IBM's
+ Common Public License Version 0.5</a> and hosted
+ on <a
+ href="http://sourceforge.net/projects/junit/">SourceForge</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="overview_8">What awards has JUnit won?</a></b>
+ </p>
+ <ul>
+ <li>
+ <p> <a
+ href="http://www.javaworld.com/javaworld/jw-03-2002/jw-0326-awards.html">2002
+ JavaWorld Editors' Choice Awards (ECA)</a>
+ </p>
+ <p>
+ Best Java Performance Monitoring/Testing Tool
+ </p>
+ </li>
+ <li>
+ <p>
+ <a
+ href="http://www.javaworld.com/javaworld/jw-06-2001/j1-01-awards.html">2001
+ JavaWorld Editors' Choice Awards (ECA)</a>
+ </p>
+ <p>
+ Best Java Performance Monitoring/Testing Tool
+ </p>
+ </li>
+ </ul>
+ </li>
+</ol>
+
+
+<!--
+
+ Getting Started
+
+-->
+<div class="header">
+<a name="started">Getting Started</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="started_1">Where do I download JUnit?</a></b>
+ </p>
+ <p>
+ The latest version of JUnit is available
+ on <a
+ href="http://sourceforge.net/project/showfiles.php?group_id=15278">SourceForge</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="started_2">How do I install JUnit?</a></b>
+ </p>
+ <ol>
+ <li>
+ <p>
+ First, <a
+ href="http://sourceforge.net/project/showfiles.php?group_id=15278">download</a>
+ the
+ latest version of JUnit, referred to below
+ as <code>junit.zip</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Then install JUnit on your platform of choice:
+ </p>
+ <p>
+ <u>Windows</u>
+ </p>
+ <p>
+ To install JUnit on Windows, follow these steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Unzip the <code>junit.zip</code> distribution file to
+ a directory referred to as <code>%JUNIT_HOME%</code>.
+ </p>
+ </li>
+ <li>Add JUnit to the classpath:
+ <p>
+ <code>set CLASSPATH=%CLASSPATH%;%JUNIT_HOME%\junit.jar</code>
+ </p>
+ </li>
+ </ol>
+ <p>
+ <u>Unix (bash)</u>
+ </p>
+ <p>
+ To install JUnit on Unix, follow these steps:
+ </p>
+ <ol>
+ <li>
+ <p>
+ Unzip the <code>junit.zip</code> distribution file to
+ a directory referred to as <code>$JUNIT_HOME</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Add JUnit to the classpath:
+ </p>
+ <p>
+ <code>export CLASSPATH=$CLASSPATH:$JUNIT_HOME/junit.jar</code>
+ </p>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <i>(Optional)</i> Unzip
+ the <code>$JUNIT_HOME/src.jar</code> file.
+ </p>
+ </li>
+ <li>
+ <p>
+ Test the installation by running the sample tests
+ distributed with JUnit. Note that the sample tests are
+ located in the installation directory directly, not
+ the <code>junit.jar</code> file. Therefore, make sure that
+ the JUnit installation directory is on your CLASSPATH. Then
+ simply type:
+ </p>
+ <div>
+ <blockquote><code>
+ java org.junit.runner.JUnitCore org.junit.tests.AllTests
+ </code></blockquote>
+ </div>
+ <p>
+ All the tests should pass with an "OK" message.
+ </p>
+ <p>
+ <i>
+ If the tests don't pass, verify
+ that <code>junit.jar</code> is in the CLASSPATH.
+ </i>
+ </p>
+ </li>
+ <li>
+ <p>
+ Finally, <a href="#overview_4">read</a> the documentation.
+ </p>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a name="started_3">How do I uninstall JUnit?</a></b>
+ </p>
+ <ol>
+ <li>
+ <p>
+ Delete the directory structure where you unzipped the JUnit
+ distribution.
+ </p>
+ </li>
+ <li>
+ <p>
+ Remove <code>junit.jar</code> from the CLASSPATH.
+ </p>
+ </li>
+ </ol>
+ <p>
+ JUnit does not modify the registry so simply removing all the
+ files will fully uninstall it.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="started_4">How do I ask questions?</a></b>
+ </p>
+ <p>
+ Questions that are not answered in
+ the <a
+ href="http://junit.sourceforge.net/doc/faq/faq.htm">FAQ</a> or
+ in the <a href="#overview_4">documentation</a> should be posted
+ to
+ the <a
+ href="http://www.jguru.com/forums/home.jsp?topic=JUnit">jGuru
+ discussion forum</a> or the <a
+ href="http://groups.yahoo.com/group/junit/">JUnit user mailing
+ list</a>.
+ </p>
+ <p>
+ Please stick to technical issues on the discussion forum and
+ mailing lists. Keep in mind that these are public, so
+ do <b>not</b> include any confidental information in your
+ questions!
+ </p>
+ <p>
+ You should also
+ read <a
+ href="http://www.catb.org/~esr/faqs/smart-questions.html">"How
+ to ask questions the smart way"</a> by Eric Raymond before
+ participating in the discussion forum and mailing lists.
+ </p>
+ <p>
+ <i>
+ NOTE: <br/> Please do NOT submit bugs, patches, or feature
+ requests to the discussion forum or mailing lists. <br/>
+ Refer instead to <a href="#started_5">"How do I submit bugs,
+ patches, or feature requests?"</a>.
+ </i>
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="started_5">How do I submit bugs, patches, or
+ feature requests?</a></b>
+ </p>
+ <p>
+ JUnit celebrates programmers testing their own software. In this
+ spirit, bugs, patches, and feature requests that include JUnit
+ tests have a better chance of being addressed than those
+ without.
+ </p>
+ <p>
+ JUnit is hosted
+ on <a
+ href="http://sourceforge.net/projects/junit">SourceForge</a>.
+ Please use the tools provided by SourceForge for your
+ submissions.
+ </p>
+ </li>
+</ol>
+
+
+<!--
+
+ Writing Tests
+
+-->
+<div class="header">
+<a name="tests">Writing Tests</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="tests_1"></a>How do I write and run a simple test?</b>
+ </p>
+ <ol>
+ <li>
+ <p>
+ Create a class:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ package junitfaq;
+
+ import org.junit.*;
+ import static org.junit.Assert.*;
+
+ import java.util.*;
+
+ public class SimpleTest {
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Write a test method (annotated with <code>@Test</code>) that
+ asserts expected results on the object under test:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ @Test
+ public void testEmptyCollection() {
+ Collection collection = new ArrayList();
+ assertTrue(collection.isEmpty());
+ }
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ If you are running your JUnit 4 tests with a JUnit 3.x runner,
+ write a <code>suite()</code> method that uses the
+ <code>JUnit4TestAdapter</code> class to create a suite
+ containing all of your test methods:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ public static junit.framework.Test suite() {
+ return new junit.framework.JUnit4TestAdapter(SimpleTest.class);
+ }
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Although writing a <code>main()</code> method to run the
+ test is much less important with the advent of IDE runners,
+ it's still possible:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ public static void main(String args[]) {
+ org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");
+ }
+ }
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Run the test:
+ </p>
+ <ul>
+ <li>
+ <p>
+ To run the test from the console, type:
+ </p>
+ <div>
+ <blockquote><code>
+java org.junit.runner.JUnitCore junitfaq.SimpleTest
+ </code></blockquote>
+ </div>
+ </li>
+ <li>
+ <p>
+ To run the test with the test runner used
+ in <code>main()</code>, type:
+ </p>
+ <div>
+ <blockquote><code>
+java junitfaq.SimpleTest
+ </code></blockquote>
+ </div>
+ </li>
+ </ul>
+ <p>
+ The passing test results in the following textual output:
+ </p>
+ <div>
+ <blockquote>
+ <pre><code>
+ .
+Time: 0
+
+OK (1 tests)
+ </code></pre>
+ </blockquote>
+ </div>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_2"></a>How do I use a test fixture?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Jeff Nielsen)</i>
+ </p>
+ <p>
+ A test fixture is useful if you have two or more tests for a
+ common set of objects. Using a test fixture avoids duplicating
+ the code necessary to initialize (and cleanup) the common
+ objects.
+ </p>
+ <p>
+ Tests can use the objects (variables) in a test fixture, with
+ each test invoking different methods on objects in the fixture
+ and asserting different expected results. Each test runs in its
+ own test fixture to isolate tests from the changes made by other
+ tests. That is, <em>tests don't share the state of objects in
+ the test fixture</em>. Because the tests are isolated, they can
+ be run in any order.
+ </p>
+ <p>
+ To create a test fixture, declare instance variables for the
+ common objects. Initialize these objects in a <code>public
+ void</code> method annotated with <code>@Before</code>. The
+ JUnit framework automatically invokes any <code>@Before</code>
+ methods before each test is run.
+ </p>
+ <p>
+ The following example shows a test fixture with a common
+ <code>Collection</code> object.
+ </p>
+ <div class="code">
+ <pre><code>
+ package junitfaq;
+
+ import org.junit.*;
+ import static org.junit.Assert.*;
+ import java.util.*;
+
+ public class SimpleTest {
+
+ private Collection&lt;Object&gt; collection;
+
+ @Before
+ public void setUp() {
+ collection = new ArrayList&lt;Object&gt;();
+ }
+
+ @Test
+ public void testEmptyCollection() {
+ assertTrue(collection.isEmpty());
+ }
+
+
+ @Test
+ public void testOneItemCollection() {
+ collection.add("itemA");
+ assertEquals(1, collection.size());
+ }
+ }
+ </code></pre>
+ </div>
+
+ <p>
+ Given this test, the methods might execute in the following
+ order:
+ </p>
+ <blockquote>
+ <pre><code>setUp()
+testEmptyCollection()
+setUp()
+testOneItemCollection()</code></pre>
+ </blockquote>
+ <p>
+ The ordering of test-method invocations is not guaranteed, so
+ <code>testOneItemCollection()</code> might be executed before
+ <code>testEmptyCollection()</code>. But it doesn't matter,
+ because each method gets its own instance of the
+ <code>collection</code>.
+ </p>
+
+ <p>
+ Although JUnit provides a new instance of the fixture objects
+ for each test method, if you allocate any <em>external</em>
+ resources in a <code>@Before</code> method, you should release
+ them after the test runs by annotating a method with
+ <code>@After</code>. The JUnit framework automatically invokes
+ any <code>@After</code> methods after each test is run. For
+ example:
+ </p>
+
+ <div class="code">
+ <pre><code>
+ package junitfaq;
+
+ import org.junit.*;
+ import static org.junit.Assert.*;
+ import java.io.*;
+
+ public class OutputTest {
+
+ private File output;
+
+ @Before
+ public void createOutputFile() {
+ output = new File(...);
+ }
+
+ @After
+ public void deleteOutputFile() {
+ output.delete();
+ }
+
+ @Test
+ public void testSomethingWithFile() {
+ ...
+ }
+ }
+ </code></pre>
+ </div>
+ <p>
+ With this test, the methods will execute in the following order:
+ </p>
+ <div>
+ <blockquote>
+ <pre><code>
+createOutputFile()
+testSomethingWithFile()
+deleteOutputFile()
+ </code></pre>
+ </blockquote>
+ </div>
+
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_4"></a>How do I test a method that doesn't
+ return anything?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Dave Astels)</i>
+ </p>
+ <p>
+ Often if a method doesn't return a value, it will have some side
+ effect. Actually, if it doesn't return a value AND doesn't have
+ a side effect, it isn't doing anything.
+ </p>
+ <p>
+ There may be a way to verify that the side effect actually
+ occurred as expected. For example, consider
+ the <code>add()</code> method in the Collection classes. There
+ are ways of verifying that the side effect happened (i.e. the
+ object was added). You can check the size and assert that it is
+ what is expected:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ @Test
+ public void testCollectionAdd() {
+ Collection collection = new ArrayList();
+ assertEquals(0, collection.size());
+ collection.add("itemA");
+ assertEquals(1, collection.size());
+ collection.add("itemB");
+ assertEquals(2, collection.size());
+ }
+ </code></pre>
+ </div>
+ <p>
+ Another approach is to make use of <a
+ href="http://www.mockobjects.com">MockObjects</a>.
+ </p>
+ <p>
+ A related issue is to design for testing. For example, if you
+ have a method that is meant to output to a file, don't pass in a
+ filename, or even a <code>FileWriter</code>. Instead, pass in
+ a <code>Writer</code>. That way you can pass in
+ a <code>StringWriter</code> to capture the output for testing
+ purposes. Then you can add a method
+ (e.g. <code>writeToFileNamed(String filename)</code>) to
+ encapsulate the <code>FileWriter</code> creation.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_5"></a>Under what conditions should I test
+ get() and set() methods?</b>
+ </p>
+ <p>
+ Unit tests are intended to alleviate fear that something might
+ break. If you think a <code>get()</code> or <code>set()</code>
+ method could reasonably break, or has in fact contributed to a
+ defect, then by all means write a test.
+ </p>
+ <p>
+ In short, test until you're confident. What you choose to test
+ is subjective, based on your experiences and confidence level.
+ Remember to be practical and maximize your testing investment.
+ </p>
+ <p>
+ Refer also to <a href="#best_3">"How simple is 'too simple to
+ break'?"</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_6"></a>Under what conditions should I not test
+ get() and set() methods?</b>
+ </p>
+ <p>
+ <i>(Submitted by: J. B. Rainsberger)</i>
+ </p>
+ <p>
+ Most of the time, get/set methods just can't break, and if they
+ can't break, then why test them? While it is usually better to
+ test more, there is a definite curve of diminishing returns on
+ test effort versus "code coverage". Remember the maxim: "Test
+ until fear turns to boredom."
+ </p>
+ <p>
+ Assume that the <code>getX()</code> method only does "return x;"
+ and that the <code>setX()</code> method only does "this.x =
+ x;". If you write this test:
+ </p>
+ <div>
+ <blockquote><pre>
+@Test
+public void testGetSetX() {
+ setX(23);
+ assertEquals(23, getX());
+}
+ </pre></blockquote>
+ </div>
+ <p>
+ then you are testing the equivalent of the following:
+ </p>
+ <div>
+ <blockquote><pre>
+@Test
+public void testGetSetX() {
+ x = 23;
+ assertEquals(23, x);
+}
+</pre></blockquote>
+ </div>
+ <p>
+ or, if you prefer,
+ </p>
+ <div>
+ <blockquote><pre>
+@Test
+public void testGetSetX() {
+ assertEquals(23, 23);
+}
+</pre></blockquote>
+ </div>
+ <p>
+ At this point, you are testing the Java compiler, or possibly
+ the interpreter, and not your component or application. There is
+ generally no need for you to do Java's testing for them.
+ </p>
+ <p>
+ If you are concerned about whether a property has already been
+ set at the point you wish to call <code>getX()</code>, then you
+ want to test the constructor, and not the <code>getX()</code>
+ method. This kind of test is especially useful if you have
+ multiple constructors:
+ </p>
+ <div>
+ <blockquote><pre>
+@Test
+public void testCreate() {
+ assertEquals(23, new MyClass(23).getX());
+}
+ </pre></blockquote>
+ </div>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_7"></a>How do I write a test that passes when
+ an expected exception is thrown?</b>
+ </p>
+ <p>
+ Add the optional <code>expected</code> attribute to
+ the <code>@Test</code> annotation. The following is an example
+ test that passes when the
+ expected <code>IndexOutOfBoundsException</code> is raised:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ @Test(expected=IndexOutOfBoundsException.class)
+ public void testIndexOutOfBoundsException() {
+ ArrayList emptyList = new ArrayList();
+ Object o = emptyList.get(0);
+ }
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_8"></a>How do I write a test that fails when
+ an unexpected exception is thrown?</b>
+ </p>
+ <p>
+ Declare the exception in the <code>throws</code> clause of the
+ test method and don't catch the exception within the test
+ method. Uncaught exceptions will cause the test to fail with an
+ error.
+ </p>
+ <p>
+ The following is an example test that fails when
+ the <code>IndexOutOfBoundsException</code> is raised:
+ </p>
+ <div class="code-red">
+ <pre><code>
+
+ @Test
+ public void testIndexOutOfBoundsExceptionNotRaised()
+ throws IndexOutOfBoundsException {
+
+ ArrayList emptyList = new ArrayList();
+ Object o = emptyList.get(0);
+ }
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_10"></a>How do I test protected methods?</b>
+ </p>
+ <p>
+ Place your tests in the same package as the classes under test.
+ </p>
+ <p>
+ Refer to <a href="#organize_1">"Where should I put my test
+ files?"</a> for examples of how to organize tests for protected
+ method access.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_11"></a>How do I test private methods?</b>
+ </p>
+ <p>
+ Testing private methods may be an indication that those methods
+ should be moved into another class to promote reusability.
+ </p>
+ <p>
+ But if you must...
+ </p>
+ <p>
+ If you are using JDK 1.3 or higher, you can use reflection to
+ subvert the access control mechanism with the aid of
+ the <a
+ href="http://sourceforge.net/projects/privaccessor/">PrivilegedAccessor</a>.
+ For details on how to use it,
+ read <a
+ href="http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.html">this
+ article</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_12"></a>Why does JUnit only report the first
+ failure in a single test?</b>
+ </p>
+ <p>
+ <i>(Submitted by: J. B. Rainsberger)</i>
+ </p>
+ <p>
+ Reporting multiple failures in a single test is generally a sign
+ that the test does too much, compared to what a unit test ought
+ to do. Usually this means either that the test is really a
+ functional/acceptance/customer test or, if it is a unit test,
+ then it is too big a unit test.
+ </p>
+ <p>
+ JUnit is designed to work best with a number of small tests. It
+ executes each test within a separate instance of the test
+ class. It reports failure on each test. Shared setup code is
+ most natural when sharing between tests. This is a design
+ decision that permeates JUnit, and when you decide to report
+ multiple failures per test, you begin to fight against
+ JUnit. This is not recommended.
+ </p>
+ <p>
+ Long tests are a design smell and indicate the likelihood of a
+ design problem. Kent Beck is fond of saying in this case that
+ "there is an opportunity to learn something about your design."
+ We would like to see a pattern language develop around these
+ problems, but it has not yet been written down.
+ </p>
+ <p>
+ Finally, note that a single test with multiple assertions is
+ isomorphic to a test case with multiple tests:
+ </p>
+ <p>
+ One test method, three assertions:
+ </p>
+ <div>
+ <blockquote><pre><code>
+public class MyTestCase {
+ @Test
+ public void testSomething() {
+ // Set up for the test, manipulating local variables
+ assertTrue(condition1);
+ assertTrue(condition2);
+ assertTrue(condition3);
+ }
+}
+ </code></pre></blockquote>
+ </div>
+ <p>
+ Three test methods, one assertion each:
+ </p>
+ <div>
+ <blockquote><pre><code>
+public class MyTestCase {
+ // Local variables become instance variables
+
+ @Before
+ public void setUp() {
+ // Set up for the test, manipulating instance variables
+ }
+
+ @Test
+ public void testCondition1() {
+ assertTrue(condition1);
+ }
+
+ @Test
+ public void testCondition2() {
+ assertTrue(condition2);
+ }
+
+ @Test
+ public void testCondition3() {
+ assertTrue(condition3);
+ }
+}
+ </code></pre></blockquote>
+ </div>
+ <p>
+ The resulting tests use JUnit's natural execution and reporting
+ mechanism and, failure in one test does not affect the execution
+ of the other tests. You generally want exactly one test to fail
+ for any given bug, if you can manage it.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_13"></a>In Java 1.4, <code>assert</code> is a
+ keyword. Won't this conflict
+ with JUnit's <code>assert()</code> method?</b>
+ </p>
+ <p>
+ JUnit 3.7 deprecated <code>assert()</code> and replaced it
+ with <code>assertTrue()</code>, which works exactly the same
+ way.
+ </p>
+ <p>
+ JUnit 4 is compatible with the <code>assert</code> keyword. If
+ you run with the <code>-ea</code> JVM switch, assertions that
+ fail will be reported by JUnit.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_14"></a>How do I test things that must be run
+ in a J2EE container (e.g. servlets, EJBs)?</b>
+ </p>
+ <p>
+ Refactoring J2EE components to delegate functionality to other
+ objects that don't have to be run in a J2EE container will
+ improve the design and testability of the software.
+ </p>
+ <p>
+ <a href="http://jakarta.apache.org/cactus/index.html">Cactus</a>
+ is an open source JUnit extension that can be used to test J2EE
+ components in their natural environment.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_15"></a>Do I need to write
+ a test class for every class I need to
+ test?</b>
+ </p>
+ <p>
+ <i>(Submitted by: J. B. Rainsberger)</i>
+ </p>
+ <p>
+ No. It is a convention to start with one test
+ class per class under test, but it is not necessary.
+ </p>
+ <p>
+ Test classes only provide a way to organize tests, nothing more.
+ Generally you will start with one test class per class under
+ test, but then you may find that a small group of tests belong
+ together with their own common test fixture.[1] In this case,
+ you may move those tests to a new test class. This is a simple
+ object-oriented refactoring: separating responsibilities of an
+ object that does too much.
+ </p>
+ <p>
+ Another point to consider is that the <code>TestSuite</code> is
+ the smallest execution unit in JUnit: you cannot execute
+ anything smaller than a TestSuite at one time without changing
+ source code. In this case, you probably do not want to put tests
+ in the same test class unless they somehow "belong together".
+ If you have two groups of tests that you think you'd like to
+ execute separately from one another, it is wise to place them in
+ separate test classes.
+ </p>
+ <p>
+ <i>
+ [1] A test fixture is a common set of test data and
+ collaborating objects shared by many tests. Generally they are
+ implemented as instance variables in the test class.
+ </i>
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_16"></a>Is there a basic template I can use to
+ create a test?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Eric Armstrong)</i>
+ </p>
+ <p>
+ The following templates are a good starting point. Copy/paste
+ and edit these templates to suit your coding style.
+ </p>
+ <p>
+ SampleTest is a basic test template:
+ </p>
+ <div>
+ <blockquote><pre><code>
+import org.junit.*;
+import static org.junit.Assert.*;
+
+public class SampleTest {
+
+ private java.util.List emptyList;
+
+ /**
+ * Sets up the test fixture.
+ * (Called before every test case method.)
+ */
+ @Before
+ public void setUp() {
+ emptyList = new java.util.ArrayList();
+ }
+
+ /**
+ * Tears down the test fixture.
+ * (Called after every test case method.)
+ */
+ @After
+ public void tearDown() {
+ emptyList = null;
+ }
+
+ @Test
+ public void testSomeBehavior() {
+ assertEquals("Empty list should have 0 elements", 0, emptyList.size());
+ }
+
+ @Test(expected=IndexOutOfBoundsException.class)
+ public void testForException() {
+ Object o = emptyList.get(0);
+ }
+}
+ </code></pre></blockquote>
+ </div>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_17"></a>How do I write a test for an abstract
+ class?</b>
+ </p>
+ <p>
+ Refer to <a
+ href="http://c2.com/cgi/wiki?AbstractTestCases">http://c2.com/cgi/wiki?AbstractTestCases</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="tests_18"></a>When are tests garbage collected?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Timothy Wall and Kent Beck)</i>
+ </p>
+ <p>
+ By design, the tree of Test instances is built in one pass, then
+ the tests are executed in a second pass. The test runner holds
+ strong references to all Test instances for the duration of the
+ test execution. This means that for a very long test run with
+ many Test instances, none of the tests may be garbage collected
+ until the end of the entire test run.
+ </p>
+ <p>
+ Therefore, if you allocate external or limited resources in a
+ test, you are responsible for freeing those resources.
+ Explicitly setting an object to <code>null</code> in
+ the <code>tearDown()</code> method, for example, allows it to be
+ garbage collected before the end of the entire test run.
+ </p>
+ </li>
+</ol>
+
+
+<!--
+
+ Organizing Tests
+
+-->
+<div class="header">
+<a name="organize">Organizing Tests</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="organize_1"></a>Where should I put my test files?</b>
+ </p>
+ <p>
+ You can place your tests in the same package and directory as
+ the classes under test.
+ </p>
+ <p>
+ For example:
+ </p>
+ <div>
+ <blockquote><pre>
+src
+ com
+ xyz
+ SomeClass.java
+ SomeClassTest.java
+ </pre></blockquote>
+ </div>
+ <p>
+ While adequate for small projects, many developers feel that
+ this approach clutters the source directory, and makes it hard
+ to package up client deliverables without also including
+ unwanted test code, or writing unnecessarily complex packaging
+ tasks.
+ </p>
+ <p>
+ An arguably better way is to place the tests in a separate
+ parallel directory structure with package alignment.
+ </p>
+ <p>
+ For example:
+ </p>
+ <div>
+ <blockquote><pre>
+src
+ com
+ xyz
+ SomeClass.java
+test
+ com
+ xyz
+ SomeClassTest.java
+ </pre></blockquote>
+ </div>
+ <p>
+ These approaches allow the tests to access to all the public and
+ package visible methods of the classes under test.
+ </p>
+ <p>
+ Some developers have argued in favor of putting the tests in a
+ sub-package of the classes under test (e.g. com.xyz.test). The
+ author of this FAQ sees no clear advantage to adopting this
+ approach and believes that said developers also put their curly
+ braces on the wrong line. :-)
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="organize_3"></a>How can I run setUp() and tearDown()
+ code once for all of my tests?</b>
+ </p>
+ <p>
+ The desire to do this is usually a symptom of excessive coupling
+ in your design. If two or more tests must share the same test
+ fixture state, then the tests may be trying to tell you that the
+ classes under test have some undesirable dependencies.
+ </p>
+ <p>
+ Refactoring the design to further decouple the classes under
+ test and eliminate code duplication is usually a better
+ investment than setting up a shared test fixture.
+ </p>
+ <p>
+ But if you must...
+ </p>
+ <p>
+ You can add a <code>@BeforeClass</code> annotation to a method
+ to be run before all the tests in a class, and
+ a <code>@AfterClass</code> annotation to a method to be run
+ after all the tests in a class. Here's an example:
+ </p>
+ <div class="code">
+ <pre><code>
+
+ package junitfaq;
+
+ import org.junit.*;
+ import static org.junit.Assert.*;
+ import java.util.*;
+
+ public class SimpleTest {
+
+ private Collection collection;
+
+ @BeforeClass
+ public static void oneTimeSetUp() {
+ // one-time initialization code
+ }
+
+ @AfterClass
+ public static void oneTimeTearDown() {
+ // one-time cleanup code
+ }
+
+ @Before
+ public void setUp() {
+ collection = new ArrayList();
+ }
+
+ @After
+ public void tearDown() {
+ collection.clear();
+ }
+
+ @Test
+ public void testEmptyCollection() {
+ assertTrue(collection.isEmpty());
+ }
+
+ @Test
+ public void testOneItemCollection() {
+ collection.add("itemA");
+ assertEquals(1, collection.size());
+ }
+ }
+ </code></pre>
+ </div>
+ <p>
+ Given this test, the methods will execute in the following
+ order:
+ </p>
+ <div>
+ <blockquote>
+ <pre><code>
+oneTimeSetUp()
+setUp()
+testEmptyCollection()
+tearDown()
+setUp()
+testOneItemCollection()
+tearDown()
+oneTimeTearDown()
+ </code></pre>
+ </blockquote>
+ </div>
+
+ </li>
+</ol>
+
+
+<!--
+
+ Running Tests
+
+-->
+<div class="header">
+<a name="running">Running Tests</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="running_1"></a>What CLASSPATH settings are needed to
+ run JUnit?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Eric Armstrong)</i>
+ </p>
+ <p>
+ To run your JUnit tests, you'll need the following elemements in
+ your CLASSPATH:
+ </p>
+ <ul>
+ <li>JUnit class files</li>
+ <li>Your class files, including your JUnit test classes</li>
+ <li>Libraries your class files depend on</li>
+ </ul>
+ <p>
+ If attempting to run your tests results in
+ a <code>NoClassDefFoundError</code>, then something is missing
+ from your CLASSPATH.
+ </p>
+ <p>
+ <u>Windows Example:</u>
+ </p>
+ <p>
+ <code>set
+ CLASSPATH=%JUNIT_HOME%\junit.jar;c:\myproject\classes;c:\myproject\lib\something.jar</code>
+ </p>
+ <p>
+ <u>Unix (bash) Example:</u>
+ </p>
+ <p>
+ <code>export CLASSPATH=$JUNIT_HOME/junit.jar:/myproject/classes:/myproject/lib/something.jar</code>
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_2"></a>Why do I get
+ a <code>NoClassDefFoundError</code> when trying to test JUnit
+ or run the samples?</b>
+ </p>
+ <p>
+ <i>(Submitted by: J.B. Rainsberger and Jason Rogers)</i>
+ </p>
+ <p>
+ Most likely your CLASSPATH doesn't include the JUnit
+ installation directory.
+ </p>
+ <p>
+ Refer to <a href="#running_1">"What CLASSPATH settings are
+ needed to run JUnit?"</a> for more guidance.
+ </p>
+ <p>
+ Also consider running <a
+ href="http://www.clarkware.com/software/WhichJUnit.zip">WhichJunit</a>
+ to print the absolute location of the JUnit class files required
+ to run and test JUnit and its samples.
+ </p>
+ <p>
+ If the CLASSPATH seems mysterious, read <a
+ href="http://java.sun.com/j2se/1.4/docs/tooldocs/findingclasses.html">this</a>!
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_4"></a>How do I run JUnit from my command window?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Eric Armstrong)</i>
+ </p>
+ <ol>
+ <li>
+ <p>
+ <a href="#running_1">Set your CLASSPATH</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Invoke the runner:
+ </p>
+ <p>
+ <code>
+ java org.junit.runner.JUnitCore &lt;test class name&gt;
+ </code>
+ </p>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_5"></a>How do I run JUnit using Ant?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Eric Armstrong)</i>
+ </p>
+ <ol>
+ <li>
+ <p>
+ Define any necessary Ant properties:
+ </p>
+ <div>
+ <pre><code>
+&lt;property name="src" value="./src" /&gt;
+&lt;property name="lib" value="./lib" /&gt;
+&lt;property name="classes" value="./classes" /&gt;
+&lt;property name="test.class.name" value="com.xyz.MyTestSuite" /&gt;
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Set up the CLASSPATH to be used by JUnit:
+ </p>
+ <div>
+ <pre><code>
+&lt;path id="test.classpath"&gt;
+ &lt;pathelement location="${classes}" /&gt;
+ &lt;pathelement location="/path/to/junit.jar" /&gt;
+ &lt;fileset dir="${lib}">
+ &lt;include name="**/*.jar"/&gt;
+ &lt;/fileset&gt;
+&lt;/path&gt;
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Define the Ant task for running JUnit:
+ </p>
+ <div>
+ <pre><code>
+&lt;target name="test"&gt;
+ &lt;junit fork="yes" haltonfailure="yes"&gt;
+ &lt;test name="${test.class.name}" /&gt;
+ &lt;formatter type="plain" usefile="false" /&gt;
+ &lt;classpath refid="test.classpath" /&gt;
+ &lt;/junit&gt;
+&lt;/target&gt;
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Run the test:
+ </p>
+ <div>
+ <code>
+ ant test
+ </code>
+ </div>
+ </li>
+ </ol>
+ <p>
+ Refer to the <a
+ href="http://jakarta.apache.org/ant/manual/OptionalTasks/junit.html">JUnit
+ Ant Task</a> for more information.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_6"></a>How do I use Ant to create HTML test
+ reports?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Eric Armstrong and Steffen Gemkow)</i>
+ </p>
+ <ol>
+ <li>
+ <p>
+ Ensure that Ant's <code>optional.jar</code> file is either
+ in your CLASSPATH or exists in
+ your <code>$ANT_HOME/lib</code> directory.
+ </p>
+ </li>
+ <li>
+ <p>
+ Add an ANT property for the directory containing the HTML reports:
+ </p>
+ <div>
+ <code>
+&lt;property name="test.reports" value="./reports" /&gt;
+ </code>
+ </div>
+ </li>
+ <li>
+ <p>
+ Define the Ant task for running JUnit and generating reports:
+ </p>
+ <div>
+ <pre><code>
+&lt;target name="test-html"&gt;
+ &lt;junit fork="yes" printsummary="no" haltonfailure="no"&gt;
+ &lt;batchtest fork="yes" todir="${test.reports}" &gt;
+ &lt;fileset dir="${classes}"&gt;
+ &lt;include name="**/*Test.class" /&gt;
+ &lt;/fileset&gt;
+ &lt;/batchtest&gt;
+ &lt;formatter type="xml" /&gt;
+ &lt;classpath refid="test.classpath" /&gt;
+ &lt;/junit&gt;
+
+ &lt;junitreport todir="${test.reports}"&gt;
+ &lt;fileset dir="${test.reports}"&gt;
+ &lt;include name="TEST-*.xml" /&gt;
+ &lt;/fileset&gt;
+ &lt;report todir="${test.reports}" /&gt;
+ &lt;/junitreport&gt;
+&lt;/target&gt;
+ </code></pre>
+ </div>
+ </li>
+ <li>
+ <p>
+ Run the test:
+ </p>
+ <div>
+ <code>
+ ant test-html
+ </code>
+ </div>
+ </li>
+ </ol>
+ <p>
+ Refer to the
+ <a href="http://jakarta.apache.org/ant/manual/OptionalTasks/junit.html">JUnit Ant Task</a>
+ for more information.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_7"></a>How do I pass command-line arguments
+ to a test execution?</b>
+ </p>
+ <p>
+ Use the <tt>-D</tt> JVM command-line options, as in:
+ </p>
+ <div>
+ <blockquote><code>
+-DparameterName=parameterValue
+ </code></blockquote>
+ </div>
+ <p>
+ If the number of parameters on the command line gets unweildy,
+ pass in the location of a property file that defines a set of
+ parameters. Alternatively, the <a
+ href="http://junit-addons.sf.net">JUnit-addons package</a>
+ contains the <tt>XMLPropertyManager</tt>
+ and <tt>PropertyManager</tt> classes that allow you to define a
+ property file (or XML file) containing test parameters.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_9"></a>Why do I get
+ a <code>LinkageError</code> when using
+ XML interfaces in my test?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Scott Stirling)</i>
+ </p>
+ <p>
+ The workaround as of JUnit 3.7 is to
+ add <code>org.w3c.dom.*</code> and <code>org.xml.sax.*</code> to
+ your <code>excluded.properties</code>.
+ </p>
+ <p>
+ It's just a matter of time before this fix becomes incorporated
+ into the released version of
+ JUnit's <code>excluded.properties</code>, since JAXP is a
+ standard part of JDK 1.4. It will be just like
+ excluding <code>org.omg.*</code>. By the way, if you download
+ the JUnit source from its Sourceforge CVS, you will find that
+ these patterns have already been added to the default
+ excluded.properties and so has a pattern for JINI. In fact, here
+ is the current version in CVS, which demonstrates how to add
+ exclusions to the list too:
+ </p>
+ <div>
+ <blockquote><pre>
+#
+# 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.*
+excluded.5=java.*
+excluded.6=org.w3c.dom.*
+excluded.7=org.xml.sax.*
+excluded.8=net.jini.*
+ </pre></blockquote>
+ </div>
+ <p>
+ This is the most common case where the
+ default <code>excluded.properties</code> list needs
+ modification. The cause of the <code>LinkageError</code> is
+ related to using JAXP in your test cases. By JAXP I mean the
+ whole set of <code>javax.xml.*</code> classes and the
+ supporting <code>org.w3c.dom.*</code>
+ and <code>org.xml.sax.*</code> classes.
+ </p>
+ <p>
+ As stated above, the JUnit GUI TestRunners' classloader relies
+ on the <code>excluded.properties</code> for classes it should
+ delegate to the system classloader. JAXP is an unusual case
+ because it is a standard Java extension library dependent on
+ classes whose package names (<code>org.w3c.dom.*</code>
+ and <code>org.xml.sax.*</code>) do not begin with a standard
+ Java or Sun prefix. This is similar to the relationship
+ between <code>javax.rmi.*</code> and the <code>org.omg.*</code>
+ classes, which have been excluded by default in
+ JUnit'ss <code>excluded.properties</code> for a while.
+ </p>
+ <p>
+ What can happen, and frequently does when using the JUnit Swing
+ or AWT UI with test cases that reference, use or depend on JAXP
+ classes, such as Log4J, Apache SOAP, Axis, Cocoon, etc., is that
+ the JUnit class loader (properly)
+ delegates <code>javax.xml.*</code> classes it &quot;sees&quot;
+ to the system loader. But then the system loader, in the process
+ of initializing and loading that JAXP class, links and loads up
+ a bunch of <code>org.w3c.dom</code>/<code>org.xml.sax</code>
+ classes. When it does so, the JUnit custom classloader is not
+ involved at all because the system classloader never delegates
+ &quot;down&quot; or checks with custom classloaders to see if a
+ class is already loaded. At any point after this, if the JUnit
+ loader is asked to load
+ an <code>org.w3c.dom</code>/<code>org.xml.sax</code> class that
+ it's never seen before, it will try to load it because the
+ class' name doesn't match any of the patterns in the default
+ exclude list. That's when a <code>LinkageError</code>
+ occurs. This is really a flaw in the JUnit classloader design,
+ but there is the workaround given above.
+ </p>
+ <p>
+ Java 2 JVMs keep classes (remember, classes and objects, though
+ related, are different entities to the JVM - I'm talking
+ about classes here, not object instances) in namespaces,
+ identifying them by their fully qualified classname plus the
+ instance of their defining (not initiating) loader. The JVM will
+ attempt to assign all unloaded classes referenced by an already
+ defined and loaded class to that class's defining loader. The
+ JVM's classresolver routine (implemented as a C function in the
+ JVM source code) keeps track of all these class loading events
+ and &quot;sees&quot; if another classloader (such as the JUnit
+ custom loader) attempts to define a class that has already been
+ defined by the system loader. According to the rules of Java 2
+ loader constraints, in case a class has already been defined by
+ the system loader, any attempts to load a class should first be
+ delegated to the system loader. A &quot;proper&quot; way for
+ JUnit to handle this feature would be to load classes from a
+ repository other than the CLASSPATH that the system classloader
+ knows nothing about. And then the JUnit custom classloader could
+ follow the standard Java 2 delegation model, which is to always
+ delegate class loading to the system loader, and only attempt to
+ load if that fails. Since they both load from the CLASSPATH in
+ the current model, if the JUnit loader delegated like it's
+ supposed to, it would never get to load any classes since the
+ system loader would always find them.
+ </p>
+ <p>
+ You could try to hack around this in the JUnit source by
+ catching the <code>LinkageError</code> in
+ TestCaseClassLoader's <code>loadClass()</code> method and then
+ making a recovery call to <code>findSystemClass()</code> --
+ thereby delegating to the system loader after the violation has
+ been caught. But this hack only works some of the time, because
+ now you can have the reverse problem where the JUnit loader will
+ load a host of <code>org.w3c.dom</code>/<code>org.xml.sax</code>
+ classes, and then the system loader violates the loader
+ contraints at some point when it tries to do exactly what I
+ described above with JAXP because it doesn't ever delegate to
+ its logical child (the JUnit loader). Inevitably, if your test
+ cases use many JAXP and related XML classes, one or the other
+ classloader will end up violating the constraints whatever you
+ do.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_11"></a>Why do I get the warning
+ "AssertionFailedError: No
+ tests found in XXX" when I run my test?</b>
+ </p>
+ <p>
+ Make sure you have more or more method annotated with <code>@Test</code>.
+ </p>
+ <p>
+ For example:
+ </p>
+ <div>
+ <blockquote><pre>
+@Test
+public void testSomething() {
+}
+ </pre></blockquote>
+ </div>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_12"></a>Why do I see "Unknown Source" in the
+ stack trace of
+a test failure, rather than the source file's line number?</b>
+ </p>
+ <p>
+ The debug option for the Java compiler must be enabled in order
+ to see source file and line number information in a stack trace.
+ </p>
+ <p>
+ When invoking the Java compiler from the command line, use
+ the <code>-g</code> option to generate all debugging info.
+ </p>
+ <p>
+ When invoking the Java compiler from an
+ <a href="http://jakarta.apache.org/ant/index.html">Ant</a> task, use the
+ <code>debug="on"</code> attribute. For example:
+ </p>
+ <div>
+ <blockquote><code>
+&lt;javac srcdir="${src}" destdir="${build}" debug="on" /&gt;
+ </code></blockquote>
+ </div>
+ <p>
+ When using older JVMs pre-Hotspot (JDK 1.1 and most/all 1.2),
+ run JUnit with the <code>-DJAVA_COMPILER=none</code> JMV command
+ line argument to prevent runtime JIT compilation from obscuring
+ line number info.
+ </p>
+ <p>
+ Compiling the test source with debug enabled will show the line
+ where the assertion failed. Compiling the non-test source with
+ debug enabled will show the line where an exception was raised
+ in the class under test.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="running_15"></a>How do I organize all test classes
+ in a TestSuite automatically and not use or manage a TestSuite
+ explicitly?</b>
+ </p>
+ <p>
+ <i>(Submitted by: Bill de hora)</i>
+ </p>
+ <p>
+ There are a number of ways to do this:
+ </p>
+ <ol>
+ <li>
+ <p>
+ In Ant, use the <code>junit</code> task and
+ the <code>batchtest</code> element:
+ </p>
+ <div>
+ <pre><code>
+&lt;junit printsummary="yes" haltonfailure="yes"&gt;
+ ...
+ &lt;batchtest fork="yes"&gt;
+ &lt;fileset dir="${src.dir}"&gt;
+ &lt;include name="**/*Test.java" /&gt;
+ &lt;include name="**/Test*.java" /&gt;
+ &lt;/fileset&gt;
+ &lt;/batchtest&gt;
+&lt;/junit&gt;
+ </code></pre>
+ </div>
+ <p>
+ Idiomatic naming patterns for unit tests
+ are <code>Test*.java</code> and <code>*Test.java</code>.
+ Documentation and examples are at <a
+ href="http://ant.apache.org/manual/OptionalTasks/junit.html">http://ant.apache.org/manual/OptionalTasks/junit.html</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Use the <code>DirectorySuiteBuilder</code>
+ and <code>ArchiveSuiteBuilder</code> (for jar/zip files)
+ classes provided by JUnit-addons project:
+ </p>
+ <div>
+ <blockquote><pre>
+DirectorySuiteBuilder builder = new DirectorySuiteBuilder();
+builder.setSuffix("Test");
+Test suite = builer.suite("/home/project/myproject/tests");
+ </pre></blockquote>
+ </div>
+ <p>
+ Documentation and examples are at <a
+ href="http://junit-addons.sourceforge.net/">http://junit-addons.sourceforge.net</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Write your own custom suite builder.
+ </p>
+ <p>
+ Have your test classes implement an interface and write a
+ treewalker to load each class in a directory, inspect the
+ class, and add any classes that implement the interface to a
+ TestSuite.
+ </p>
+ <p>
+ You might only want to do this if you are <b>very</b>
+ uncomfortable with using a naming convention for test
+ classes. Aside from being slow for larger suites, ultimately
+ it's arguable whether it's more effort to follow a naming
+ convention that have test classes implement an interface!
+ </p>
+ <p>
+ An example of this approach is at
+ <a href="http://www.javaworld.com/javaworld/jw-12-2000/jw-1221-junit_p.html">http://www.javaworld.com/javaworld/jw-12-2000/jw-1221-junit_p.html</a>.
+ </p>
+ </li>
+ </ol>
+ </li>
+</ol>
+
+<!--
+
+ Best Practices
+
+-->
+<div class="header">
+<a name="best">Best Practices</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="best_1"></a>When should tests be written?</b>
+ </p>
+ <p>
+ Tests should be written before the code. Test-first programming
+ is practiced by only writing new code when an automated test is
+ failing.
+ </p>
+ <p>
+ Good tests tell you how to best design the system for its
+ intended use. They effectively communicate in an executable
+ format how to use the software. They also prevent tendencies to
+ over-build the system based on speculation. When all the tests
+ pass, you know you're done!
+ </p>
+ <p>
+ Whenever a customer test fails or a bug is reported, first write
+ the necessary unit test(s) to expose the bug(s), <em>then</em>
+ fix them. This makes it almost impossible for that particular
+ bug to resurface later.
+ </p>
+ <p>
+ Test-driven development is a lot more fun than writing tests
+ after the code seems to be working. Give it a try!
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_2"></a>Do I have to write a test for
+ everything?</b>
+ </p>
+ <p>
+ No, just test everything that could reasonably break.
+ </p>
+ <p>
+ Be practical and maximize your testing investment. Remember
+ that investments in testing are equal investments in design. If
+ defects aren't being reported and your design responds well to
+ change, then you're probably testing enough. If you're spending
+ a lot of time fixing defects and your design is difficult to
+ grow, you should write more tests.
+ </p>
+ <p>
+ If something is difficult to test, it's usually an opportunity
+ for a design improvement. Look to improve the design so that
+ it's easier to test, and by doing so a better design will
+ usually emerge.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_3"></a>How simple is 'too simple to break'?</b>
+ </p>
+ <p>
+ <i>(Submitted by: J. B. Rainsberger)</i>
+ </p>
+ <p>
+ The general philosophy is this: if it can't break <em>on its
+ own</em>, it's too simple to break.
+ </p>
+ <p>
+ First example is the <code>getX()</code> method. Suppose
+ the <code>getX()</code> method only answers the value of an
+ instance variable. In that case, <code>getX()</code> cannot
+ break unless either the compiler or the interpreter is also
+ broken. For that reason, don't test <code>getX()</code>; there
+ is no benefit. The same is true of the <code>setX()</code>
+ method, although if your <code>setX()</code> method does any
+ parameter validation or has any side effects, you likely need to
+ test it.
+ </p>
+ <p>
+ Next example: suppose you have written a method that does
+ nothing but forward parameters into a method called on another
+ object. That method is too simple to break.
+ </p>
+ <div>
+ <blockquote><pre>
+public void myMethod(final int a, final String b) {
+ myCollaborator.anotherMethod(a, b);
+}
+ </pre></blockquote>
+ </div>
+ <p>
+ <code>myMethod</code> cannot possibly break because it does nothing: it
+ forwards its input to another object and that's all.
+ </p>
+ <p>
+ The only precondition for this method is "myCollaborator !=
+ null", but that is generally the responsibility of the
+ constructor, and not of myMethod. If you are concerned, add a
+ test to verify that myCollaborator is always set to something
+ non-null by every constructor.
+ </p>
+ <p>
+ The only way myMethod could break would be
+ if <code>myCollaborator.anotherMethod()</code> were broken. In
+ that case, test <code>myCollaborator</code>, and not the current
+ class.
+ </p>
+ <p>
+ It is true that adding tests for even these simple methods
+ guards against the possibility that someone refactors and makes
+ the methods "not-so-simple" anymore. In that case, though, the
+ refactorer needs to be aware that the method is now complex
+ enough to break, and should write tests for it -- and preferably
+ before the refactoring.
+ </p>
+ <p>
+ Another example: suppose you have a JSP and, like a good
+ programmer, you have removed all business logic from it. All it
+ does is provide a layout for a number of JavaBeans and never
+ does anything that could change the value of any object. That
+ JSP is too simple to break, and since JSPs are notoriously
+ annoying to test, you should strive to make all your JSPs too
+ simple to break.
+ </p>
+ <p>
+ Here's the way testing goes:
+ </p>
+ <div>
+ <blockquote><pre>
+becomeTimidAndTestEverything
+while writingTheSameThingOverAndOverAgain
+ becomeMoreAggressive
+ writeFewerTests
+ writeTestsForMoreInterestingCases
+ if getBurnedByStupidDefect
+ feelStupid
+ becomeTimidAndTestEverything
+ end
+end
+ </pre></blockquote>
+ </div>
+ <p>
+ The loop, as you can see, never terminates.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_4"></a>How often should I run my tests?</b>
+ </p>
+ <p>
+ Run all your unit tests as often as possible, ideally every time
+ the code is changed. Make sure all your unit tests always run
+ at 100%. Frequent testing gives you confidence that your
+ changes didn't break anything and generally lowers the stress of
+ programming in the dark.
+ </p>
+ <p>
+ For larger systems, you may just run specific test suites that
+ are relevant to the code you're working on.
+ </p>
+ <p>
+ Run all your acceptance, integration, stress, and unit tests at
+ least once per day (or night).
+ </p>
+ <p>
+ If you're using Eclipse, be sure to check out David Saff's
+ <a href="http://pag.csail.mit.edu/continuoustesting/">continuous
+ testing plug-in</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_5"></a>What do I do when a defect is reported?</b>
+ </p>
+ <p>
+ Test-driven development generally lowers the defect density of
+ software. But we're all fallible, so sometimes a defect will
+ slip through. When this happens, write a failing test that
+ exposes the defect. When the test passes, you know the defect
+ is fixed!
+ </p>
+ <p>
+ Don't forget to use this as a learning opportunity. Perhaps the
+ defect could have been prevented by being more aggressive about
+ testing everything that could reasonably break.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_6"></a>Why not just use <code>System.out.println()</code>?</b>
+ </p>
+ <p>
+ Inserting debug statements into code is a low-tech method for
+ debugging it. It usually requires that output be scanned
+ manually every time the program is run to ensure that the code
+ is doing what's expected.
+ </p>
+ <p>
+ It generally takes less time in the long run to codify
+ expectations in the form of an automated JUnit test that retains
+ its value over time. If it's difficult to write a test to
+ assert expectations, the tests may be telling you that shorter
+ and more cohesive methods would improve your design.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="best_7"></a>Why not just use a debugger?</b>
+ </p>
+ <p>
+ Debuggers are commonly used to step through code and inspect
+ that the variables along the way contain the expected values.
+ But stepping through a program in a debugger is a manual process
+ that requires tedious visual inspections. In essence, the
+ debugging session is nothing more than a manual check of
+ expected vs. actual results. Moreover, every time the program
+ changes we must manually step back through the program in the
+ debugger to ensure that nothing broke.
+ </p>
+ <p>
+ It generally takes less time to codify expectations in the form
+ of an automated JUnit test that retains its value over time. If
+ it's difficult to write a test to assert expected values, the
+ tests may be telling you that shorter and more cohesive methods
+ would improve your design.
+ </p>
+ </li>
+</ol>
+
+<!--
+
+ Miscellaneous
+
+-->
+<div class="header">
+<a name="misc">Miscellaneous</a>
+</div>
+<ol>
+ <li>
+ <p>
+ <b><a name="misc_1"></a>How do I integrate JUnit with my IDE?</b>
+ </p>
+ <p>
+ The JUnit home page maintains a list of <a
+ href="http://www.junit.org/news/ide/index.htm">IDE integration
+ instructions</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="misc_2"></a>How do I launch a debugger when a test fails?</b>
+ </p>
+ <p>
+ Start the <code>TestRunner</code> under the debugger and
+ configure the debugger so that it catches
+ the <code>junit.framework.AssertionFailedError</code>.
+ </p>
+ <p>
+ How you configure this depends on the debugger you prefer to
+ use. Most Java debuggers provide support to stop the program
+ when a specific exception is raised.
+ </p>
+ <p>
+ Notice that this will only launch the debugger when an expected
+ failure occurs.
+ </p>
+ </li>
+ <li>
+ <p>
+ <b><a name="misc_3"></a>Where can I find unit testing frameworks
+ similar to JUnit for other languages?</b>
+ </p>
+ <p>
+ XProgramming.com maintains a complete list of available <a
+ href="http://www.xprogramming.com/software.htm">xUnit testing
+ frameworks</a>.
+ </p>
+ </li>
+</ol>
+
+<br/>
+
+<div align="right">
+ <a href="http://validator.w3.org/check?uri=referer">
+ <img src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+</div>
+
+</body>
+</html>
diff --git a/junit4/doc/homepage.html b/junit4/doc/homepage.html
new file mode 100644
index 0000000..ff2a027
--- /dev/null
+++ b/junit4/doc/homepage.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0029)http://junit.sourceforge.net/ -->
+<HTML><HEAD><TITLE>JUnit</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<META content="MSHTML 6.00.2712.300" name=GENERATOR>
+<META content="Erich Gamma" name=Author></HEAD>
+<BODY>
+<H1><B><FONT color=#00cc00>J</FONT><FONT color=#ff0000>U</FONT><FONT
+color=#000000>nit </FONT></B></H1>
+<P>JUnit is a simple framework to write repeatable tests. It is an instance of
+the xUnit architecture for unit testing frameworks.
+<UL>
+ <LI><A href="http://junit.sourceforge.net/#Getting">Getting Started</A>
+
+ <LI><A href="http://junit.sourceforge.net/#Documentation">Documentation</A>
+ <LI><A href="http://junit.sourceforge.net/#Related">JUnit related
+ sites/projects</A> </LI>
+ <LI><A href="http://junit.sourceforge.net/#Mail">Mailing Lists</A></LI>
+ <LI><A href="http://junit.sourceforge.net/#Developer">Get Involved</A></LI>
+</UL>
+
+<h2>
+<a NAME="Getting"></a>Getting Started</h2>
+
+To get started with unit testing and JUnit read the article:
+<a href="doc/cookbook/cookbook.htm">JUnit Cookbook</a>.
+<br>This article describes basic test writing using JUnit 4.
+<p>You find additional samples in the org.junit.samples package:
+<ul>
+<li>
+SimpleTest.java - some simple test cases</li>
+
+<li>
+VectorTest.java - test cases for java.util.Vector</li>
+</ul>
+<P>JUnit 4.x only comes with a textual TestRunner. For graphical feedback,
+most major IDE's support
+JUnit 4. If necessary, you can run JUnit 4 tests in a JUnit 3
+environment by adding the following method to each test class:
+<pre>
+public static Test suite() {
+ return new JUnit4TestAdapter(ThisClass.class);
+}
+
+</pre>
+
+<h2>
+<a NAME="Documentation"></a>Documentation</h2>
+
+<blockquote><a href="doc/cookbook/cookbook.htm">JUnit Cookbook</a>
+<br>&nbsp;&nbsp;&nbsp; A cookbook for implementing tests with JUnit.
+<br><a href="javadoc_40/index.html">Javadoc</a>
+<br>&nbsp;&nbsp;&nbsp; API documentation generated with javadoc.
+<br><a href="doc/faq/faq.htm">Frequently asked questions</a>
+<br>&nbsp;&nbsp;&nbsp; Some frequently asked questions about using JUnit.
+
+<br><a href="README.html">Release notes</a>
+<br>&nbsp;&nbsp;&nbsp; Latest JUnit release notes
+<br><a href="cpl-v10.html">License</a>
+<br>&nbsp;&nbsp;&nbsp; The terms of the common public license used for JUnit.<br>
+</blockquote>
+The following documents still describe JUnit 3.8.
+<blockquote>
+<br><a href="junit3.8.1/index.html">The JUnit 3.8 version of this homepage</a>
+<br><a href="doc/testinfected/testing.htm">Test Infected - Programmers
+Love Writing Tests</a>
+<br>&nbsp;&nbsp;&nbsp; An article demonstrating the development process
+with JUnit.
+
+<br><a href="doc/cookstour/cookstour.htm">JUnit - A cooks tour</a>
+</blockquote>
+
+<H2><A name=Related></A>JUnit Related Projects/Sites</H2>
+<UL>
+ <LI><A href="http://www.junit.org/">junit.org</A> - a site for software
+ developers using JUnit. It provides instructions for how to integrate JUnit
+ with development tools like JBuilder and VisualAge/Java. As well as articles
+ about and extensions to JUnit.</LI>
+ <LI><A href="http://www.xprogramming.com/software.htm">XProgramming.com</A> -
+ various implementations of the xUnit testing framework architecture.&nbsp;</LI>
+
+</UL>
+<H2><A name=Mail></A>Mailing Lists</H2>
+There are three junit mailing lists:
+<UL>
+ <LI>JUnit announce: junit-announce@lists.sourceforge.net <A
+ href="http://lists.sourceforge.net/lists/listinfo/junit-announce">Archives/Subscribe/Unsubscribe</A></LI>
+ <LI>JUnit users list: junit@yahoogroups.com <A
+ href="http://groups.yahoo.com/group/junit/">Archives/Subscribe/Unsubscribe</A></LI>
+ <LI>JUnit developer list: junit-devel@lists.sourceforge.net <A
+ href="http://lists.sourceforge.net/lists/listinfo/junit-devel">Archives/Subscribe/Unsubscribe</A></LI>
+
+ </UL>
+
+ <H2><A name=Developer></A>Get Involved</H2>
+ JUnit celebrates programmers testing their own software. As a result
+ bugs, patches, and feature requests which include JUnit TestCases have a
+ better
+ chance of being addressed than those without.
+
+ <br/>
+ JUnit is forged on
+ Sourceforge please use the tools <A
+ href="http://sf.net/projects/junit">provided</A> for your submissions.
+
+ <br/>
+ JUnit source code is now hosted on <a href="http://github.com/KentBeck/junit">GitHub</a>.
+
+<hr WIDTH="100%">
+<font size="1">
+hosted by </font> <A href="http://sourceforge.net"><IMG src="http://sourceforge.net/sflogo.php?group_id=15278" width="88" height="31"
+border="0" alt="SourceForge Logo"></A>
+</font>
+
+</BODY></HTML>
diff --git a/junit4/doc/index.htm b/junit4/doc/index.htm
new file mode 100644
index 0000000..dd19ff3
--- /dev/null
+++ b/junit4/doc/index.htm
@@ -0,0 +1,21 @@
+<!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="Author" content="Erich Gamma">
+ <title>JUnit Documentation</title>
+</head>
+<body>
+
+<h1>
+<font color="#33FF33">J</font><font color="#CC0000">U</font>nit Documentation</h1>
+
+<p>
+Kent Beck, Erich Gamma, David Saff</p>
+
+<hr WIDTH="100%">
+We have just begun documenting the new JUnit 4 architecture. The <a href="cookbook/cookbook.htm">cookbook</a> has already been updated. You can find the javadoc <a href="../javadoc/index.html">here</a>.
+The JUnit home page is <a href="http://www.junit.org">here</a>.
+<hr WIDTH="100%">
+</body>
+</html>
diff --git a/junit4/doc/markdown.sh b/junit4/doc/markdown.sh
new file mode 100644
index 0000000..e235b63
--- /dev/null
+++ b/junit4/doc/markdown.sh
@@ -0,0 +1 @@
+~/bin/Markdown.pl ReleaseNotes4.8.txt >ReleaseNotes4.8.html \ No newline at end of file
diff --git a/junit4/doc/testinfected/IMG00001.GIF b/junit4/doc/testinfected/IMG00001.GIF
new file mode 100644
index 0000000..ca491c1
--- /dev/null
+++ b/junit4/doc/testinfected/IMG00001.GIF
Binary files differ
diff --git a/junit4/doc/testinfected/IMG00002.GIF b/junit4/doc/testinfected/IMG00002.GIF
new file mode 100644
index 0000000..2fc614f
--- /dev/null
+++ b/junit4/doc/testinfected/IMG00002.GIF
Binary files differ
diff --git a/junit4/doc/testinfected/IMG00003.GIF b/junit4/doc/testinfected/IMG00003.GIF
new file mode 100644
index 0000000..2695af3
--- /dev/null
+++ b/junit4/doc/testinfected/IMG00003.GIF
Binary files differ
diff --git a/junit4/doc/testinfected/logo.gif b/junit4/doc/testinfected/logo.gif
new file mode 100644
index 0000000..d0e1547
--- /dev/null
+++ b/junit4/doc/testinfected/logo.gif
Binary files differ
diff --git a/junit4/doc/testinfected/testing.htm b/junit4/doc/testinfected/testing.htm
new file mode 100644
index 0000000..d11c11c
--- /dev/null
+++ b/junit4/doc/testinfected/testing.htm
@@ -0,0 +1,617 @@
+<!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="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+ <title>Test Infected: </title>
+</head>
+<body>
+
+<h1>
+<b><font color="#00CC00">J</font><font color="#FF0000">U</font><font color="#000000">nit</font> <font size=+3>Test
+Infected: Programmers Love Writing Tests</font></b></h1>
+<br>Note: this article describes JUnit 3.8.x.
+
+<hr WIDTH="100%">
+<p>Testing is not closely integrated with development. This prevents you
+from measuring the progress of development- you can't tell when something
+starts working or when something stops working. Using <i>JUnit</i> you
+can cheaply and incrementally build a test suite that will help you measure
+your progress, spot unintended side effects, and focus your development
+efforts.
+<h1>
+Contents</h1>
+
+<ul>
+<li>
+<a href="#TheProblem">The Problem</a></li>
+
+<li>
+<a href="#Example">Example</a></li>
+
+<li>
+<a href="#TestingPractices">Testing Practices</a></li>
+
+<li>
+<a href="#Conclusion">Conclusions</a></li>
+</ul>
+
+<h1>
+<a NAME="TheProblem"></a>The Problem</h1>
+Every programmer knows they should write tests for their code. Few do.
+The universal response to "Why not?" is "I'm in too much of a hurry." This
+quickly becomes a vicious cycle- the more pressure you feel, the fewer
+tests you write. The fewer tests you write, the less productive you are
+and the less stable your code becomes. The less productive and accurate
+you are, the more pressure you feel.
+<p>Programmers burn out from just such cycles. Breaking out requires an
+outside influence. We found the outside influence we needed in a simple
+testing framework that lets us do a little testing that makes a big difference.
+<p>The best way to convince you of the value of writing your own tests
+would be to sit down with you and do a bit of development. Along the way,
+we would encounter new bugs, catch them with tests, fix them, have them
+come back, fix them again, and so on. You would see the value of the immediate
+feedback you get from writing and saving and rerunning your own unit tests.
+<p>Unfortunately, this is an article, not an office overlooking charming
+old-town Z&uuml;rich, with the bustle of medieval commerce outside and
+the thump of techno from the record store downstairs, so we'll have to
+simulate the process of development. We'll write a simple program and its
+tests, and show you the results of running the tests. This way you can
+get a feel for the process we use and advocate without having to pay for
+our presence.
+<h1>
+<a NAME="Example"></a>Example</h1>
+As you read, pay attention to the interplay of the code and the tests.
+The style here is to write a few lines of code, then a test that should
+run, or even better, to write a test that won't run, then write the code
+that will make it run.
+<p>The program we write will solve the problem of representing arithmetic
+with multiple currencies. Arithmetic between single currencies is trivial,
+you can just add the two amounts. Simple numbers suffice. You can ignore
+the presence of currencies altogether.
+<p>Things get more interesting once multiple currencies are involved. You
+cannot just convert one currency into another for doing arithmetic since
+there is no single conversion rate- you may need to compare the value of
+a portfolio at yesterday's rate and today's rate.
+<p>Let's start simple and define a class <a href="#classMoney">Money</a>
+to represent a value in a single currency. We represent the amount by a
+simple int. To get full accuracy you would probably use double or java.math.BigDecimal
+to store arbitrary-precision signed decimal numbers. We represent a currency
+as a string holding the ISO three letter abbreviation (USD, CHF, etc.).
+In more complex implementations, currency might deserve its own object.
+<pre><a NAME="classMoney"></a><tt>class Money {
+&nbsp;&nbsp;&nbsp; private int fAmount;
+&nbsp;&nbsp;&nbsp; private String fCurrency;</tt></pre>
+
+<pre><tt>&nbsp;&nbsp;&nbsp; public Money(int amount, String currency) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fAmount= amount;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fCurrency= currency;
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; public int amount() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fAmount;
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; public String currency() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fCurrency;
+&nbsp;&nbsp;&nbsp; }
+}</tt></pre>
+When<font size=-1> </font>you add two Moneys of the same currency, the
+resulting Money has as its amount the sum of the other two amounts.
+<pre><a NAME="MoneyAdd"></a><tt>public Money add(Money m) {
+&nbsp;&nbsp;&nbsp; return new Money(amount()+m.amount(), currency());
+}</tt></pre>
+Now, instead of just coding on, we want to get immediate feedback and practice
+"code a little, test a little, code a little, test a little". To implement
+our tests we use the JUnit framework. To write tests you need to get the
+<a href="http://sourceforge.net/projects/junit/">latest
+copy</a> JUnit (or write your own equivalent- it's not so much work).
+<p>JUnit defines how to structure your test cases and provides the tools
+to run them. You implement a test in a subclass of TestCase. To test our
+Money implementation we therefore define <a href="#class MoneyTest">MoneyTest</a>
+as a subclass of TestCase. In Java, classes are contained in packages and
+we have to decide where to put MoneyTest. Our current practice is to put
+MoneyTest in the same package as the classes under test. In this way a
+test case has access to the package private methods. We add a test method
+testSimpleAdd, that will exercise the simple version of <a href="#MoneyAdd">Money.add()</a>
+above. A JUnit test method is an ordinary method without any parameters.
+<pre><a NAME="class MoneyTest"></a><tt>public class MoneyTest extends TestCase {
+&nbsp;&nbsp;&nbsp; //…
+&nbsp;&nbsp;&nbsp; public void testSimpleAdd() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Money m12CHF= new Money(12, "CHF");&nbsp; //&nbsp;<a NAME="MoneyTest1"></a>(1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Money m14CHF= new Money(14, "CHF");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Money expected= new Money(26, "CHF");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Money result= m12CHF.add(m14CHF);&nbsp;&nbsp;&nbsp; //&nbsp;<a NAME="MoneyTest2"></a>(2)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assert.assertTrue(expected.equals(result));&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;<a NAME="MoneyTest3"></a>(3)
+&nbsp;&nbsp;&nbsp; }
+}</tt></pre>
+The testSimpleAdd() test case consists of:
+<ol>
+<li>
+<a href="#MoneyTest1">Code</a> which creates the objects we will interact
+with during the test. This testing context is commonly referred to as a
+test's<i> fixture</i>. All we need for the testSimpleAdd test are some
+Money objects.</li>
+
+<li>
+<a href="#MoneyTest2">Code</a> which exercises the objects in the fixture.</li>
+
+<li>
+<a href="#MoneyTest3">Code</a> which verifies the result.</li>
+</ol>
+Before we can verify the result we have to digress a little since we need
+a way to test that two Money objects are equal. The Java idiom to do so
+is to override the method <i>equals</i> defined in Object. Before we implement
+equals let's a write a test for equals in MoneyTest.
+<pre><tt>public void testEquals() {
+&nbsp;&nbsp;&nbsp; Money m12CHF= new Money(12, "CHF");
+&nbsp;&nbsp;&nbsp; Money m14CHF= new Money(14, "CHF");
+
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!m12CHF.equals(null));
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(m12CHF, m12CHF);
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(m12CHF, new Money(12, "CHF")); //&nbsp;<a NAME="TestEquals1"></a>(1)
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!m12CHF.equals(m14CHF));
+}</tt></pre>
+The equals method in Object returns true when both objects are the same.
+However, Money is a <i>value object</i>. Two Monies are considered equal
+if they have the same currency and value. To test this property we have
+added a test <a href="#TestEquals1">(1)</a> to verify that Monies are equal
+when they have the same value but are not the same object.
+<p>Next let's write the equals method in Money:
+<pre><tt>public boolean equals(Object anObject) {
+&nbsp;&nbsp;&nbsp; if (anObject instanceof Money) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Money aMoney= (Money)anObject;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return aMoney.currency().equals(currency())
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; amount() == aMoney.amount();
+&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; return false;
+}</tt></pre>
+Since equals can receive any kind of object as its argument we first have
+to check its type before we cast it as a Money. As an aside, it is a recommended
+practice to also override the method hashCode whenever you override method
+equals. However, we want to get back to our test case.
+<p>With an equals method in hand we can verify the outcome of testSimpleAdd.
+In JUnit you do so by a calling
+<A HREF="../../javadoc/junit/framework/Assert.html#assertTrue(boolean)">Assert.assertTrue</a>,
+which triggers a failure that is recorded by JUnit when the argument isn't
+true. Since assertions for equality are very common, there is also
+an Assert.assertEquals convenience method. In addition to testing for equality
+with equals, it reports the printed value of the two objects in the case they
+differ. This lets us immediately see why a test failed in a JUnit test
+result report. The value a string representation created by
+the toString converter method.
+There are <a href="../../javadoc/junit/framework/Assert.html">
+other asertXXXX variants</a> not discussed here.
+<p>Now that we have implemented two test cases we notice some code duplication
+for setting-up the tests. It would be nice to reuse some of this test set-up
+code. In other words, we would like to have a common fixture for running
+the tests. With JUnit you can do so by storing the fixture's objects in
+instance variables of your
+<a href="../../javadoc/junit/framework/TestCase.html">TestCase</a>
+subclass and initialize them by overridding
+the setUp method. The symmetric operation to setUp is tearDown which you
+can override to clean up the test fixture at the end of a test. Each test
+runs in its own fixture and JUnit calls setUp and tearDown for each test
+so that there can be no side effects among test runs.
+<pre><tt>public class MoneyTest extends TestCase {
+&nbsp;&nbsp;&nbsp; private Money f12CHF;
+&nbsp;&nbsp;&nbsp; private Money f14CHF;&nbsp;&nbsp;&nbsp;
+
+&nbsp;&nbsp;&nbsp; protected void setUp() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f12CHF= new Money(12, "CHF");
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f14CHF= new Money(14, "CHF");
+&nbsp;&nbsp;&nbsp; }
+}</tt></pre>
+We can rewrite the two test case methods, removing the common setup code:
+<pre><tt>public void testEquals() {
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!f12CHF.equals(null));
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(f12CHF, f12CHF);
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(f12CHF, new Money(12, "CHF"));
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!f12CHF.equals(f14CHF));
+}
+
+public void testSimpleAdd() {
+&nbsp;&nbsp;&nbsp; Money expected= new Money(26, "CHF");
+&nbsp;&nbsp;&nbsp; Money result= f12CHF.add(f14CHF);
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(expected.equals(result));
+}</tt></pre>
+Two additional steps are needed to run the two test cases:
+<ol>
+<li>
+define how to run an individual test case,</li>
+
+<li>
+define how to run a <i>test suite</i>.</li>
+</ol>
+JUnit supports two ways of running single tests:
+<ul>
+<li>
+static</li>
+
+<li>
+dynamic</li>
+</ul>
+In the static way you override the runTest method inherited from TestCase
+and call the desired test case. A convenient way to do this is with an
+anonymous inner class. Note that each test must be given a name, so you
+can identify it if it fails.
+<pre><tt>TestCase test= new MoneyTest("simple add") {
+&nbsp;&nbsp;&nbsp; public void runTest() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testSimpleAdd();
+&nbsp;&nbsp;&nbsp; }
+};</tt></pre>
+A template method<a href="#Gamma, E., et al. Design Patterns: Elements of">[1]</a>
+in the superclass will make sure runTest is executed when the time comes.
+<p>The dynamic way to create a test case to be run uses reflection to implement
+runTest. It assumes the name of the test is the name of the test case method
+to invoke. It dynamically finds and invokes the test method. To invoke
+the testSimpleAdd test we therefore construct a MoneyTest as shown below:
+<pre><tt>TestCase test= new MoneyTest("testSimpleAdd");</tt></pre>
+The dynamic way is more compact to write but it is less static type safe.
+An error in the name of the test case goes unnoticed until you run it and
+get a NoSuchMethodException. Since both approaches have advantages, we
+decided to leave the choice of which to use up to you.
+<p>As the last step to getting both test cases to run together, we have
+to define a test suite. In JUnit this requires the definition of a static
+method called suite. The suite method is like a main method that is specialized
+to run tests. Inside suite you add the tests to be run to a
+<a href="../../javadoc/junit/framework/TestSuite.html">TestSuite</a> object
+and return it. A TestSuite can run a collection of tests. TestSuite and
+TestCase both implement an interface called Test which defines the methods
+to run a test. This enables the creation of test suites by composing arbitrary
+TestCases and TestSuites. In short TestSuite is a Composite <a href="#Gamma, E., et al. Design Patterns: Elements of">[1].</a>
+The code below illustrates the creation of a test suite with the dynamic
+way to run a test.
+<pre><tt>public static Test suite() {
+&nbsp;&nbsp;&nbsp; TestSuite suite= new TestSuite();
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testEquals"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testSimpleAdd"));
+&nbsp;&nbsp;&nbsp; return suite;
+}</tt></pre>
+Since JUnit 2.0 there is an even simpler dynamic way. You only pass the
+class with the tests to a TestSuite and it extracts the test methods automatically.
+<p><tt>public static Test suite() {<br>
+&nbsp;&nbsp;&nbsp; return new TestSuite(MoneyTest.class);<br>
+}</tt><tt></tt>
+<p>Here is the corresponding code using the static way.
+<pre><tt>public static Test suite() {
+&nbsp;&nbsp;&nbsp; TestSuite suite= new TestSuite();
+&nbsp;&nbsp;&nbsp; suite.addTest(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new MoneyTest("money equals") {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void runTest() { testEquals(); }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; );
+&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp; suite.addTest(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new MoneyTest("simple add") {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected void runTest() { testSimpleAdd(); }
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; );
+&nbsp;&nbsp;&nbsp; return suite;
+}</tt></pre>
+Now we are ready to run our tests. JUnit comes with a graphical&nbsp; interface
+to run tests. Type the name of your test class in the field at the top
+of the window. Press the Run button. While the test is run JUnit shows
+its progress with a progress bar below the input field. The bar is initially
+green but turns into red as soon as there is an unsuccessful test. Failed
+tests are shown in a list at the bottom. <a href="#Figure1">Figure 1</a>
+shows the TestRunner window after we run our trivial test suite.
+<center><img SRC="IMG00001.GIF" >
+<br><a NAME="Figure1"></a><b>Figure 1</b>: A Successful Run</center>
+
+<p>After having verified that the simple currency case works we move on
+to multiple currencies. As mentioned above the problem of mixed currency
+arithmetic is that there isn't a single exchange rate. To avoid this problem
+we introduce a MoneyBag which defers exchange rate conversions. For example
+adding 12 Swiss Francs to 14 US Dollars is represented as a bag containing
+the two Monies 12 CHF and 14 USD. Adding another 10 Swiss francs gives
+a bag with 22 CHF and 14 USD. We can later evaluate a MoneyBag with different
+exchange rates.
+<p>A MoneyBag is represented as a list of Monies and provides different
+constructors to create a MoneyBag. Note, that the constructors are package
+private since MoneyBags are created behind the scenes when doing currency
+arithmetic.
+<pre><tt>class MoneyBag {
+&nbsp;&nbsp;&nbsp; private Vector fMonies= new Vector();
+
+&nbsp;&nbsp;&nbsp; MoneyBag(Money m1, Money m2) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appendMoney(m1);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appendMoney(m2);
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; MoneyBag(Money bag[]) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i= 0; i &lt; bag.length; i++)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appendMoney(bag[i]);
+&nbsp;&nbsp;&nbsp; }
+}</tt></pre>
+The method appendMoney is an internal helper method that adds a Money to
+the list of Moneys and takes care of consolidating Monies with the same
+currency. MoneyBag also needs an equals method together with a corresponding
+test. We skip the implementation of equals and only show the testBagEquals
+method. In a first step we extend the fixture to include two MoneyBags.
+<pre><tt>protected void setUp() {
+&nbsp;&nbsp;&nbsp; f12CHF= new Money(12, "CHF");
+&nbsp;&nbsp;&nbsp; f14CHF= new Money(14, "CHF");
+&nbsp;&nbsp;&nbsp; f7USD=&nbsp; new Money( 7, "USD");
+&nbsp;&nbsp;&nbsp; f21USD= new Money(21, "USD");
+&nbsp;&nbsp;&nbsp; fMB1= new MoneyBag(f12CHF, f7USD);
+&nbsp;&nbsp;&nbsp; fMB2= new MoneyBag(f14CHF, f21USD);
+}</tt></pre>
+With this fixture the testBagEquals test case becomes:
+<pre><tt>public void testBagEquals() {
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!fMB1.equals(null));
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(fMB1, fMB1);
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!fMB1.equals(f12CHF));
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!f12CHF.equals(fMB1));
+&nbsp;&nbsp;&nbsp; Assert.assertTrue(!fMB1.equals(fMB2));
+}</tt></pre>
+Following "code a little, test a little" we run our extended test with
+JUnit and verify that we are still doing fine. With MoneyBag in hand, we
+can now fix the add method in Money.
+<pre><tt>public Money add(Money m) {
+&nbsp;&nbsp;&nbsp; if (m.currency().equals(currency()) )
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Money(amount()+m.amount(), currency());
+&nbsp;&nbsp;&nbsp; return new MoneyBag(this, m);
+}</tt></pre>
+As defined above this method will not compile since it expects a Money
+and not a MoneyBag as its return value. With the introduction of MoneyBag
+there are now two representations for Moneys which we would like to hide
+from the client code. To do so we introduce an interface IMoney that both
+representations implement. Here is the IMoney interface:
+<pre><tt>interface IMoney {
+&nbsp;&nbsp;&nbsp; public abstract IMoney add(IMoney aMoney);
+&nbsp;&nbsp;&nbsp; //…
+}</tt></pre>
+To fully hide the different representations from the client we have to
+support arithmetic between all combinations of Moneys with MoneyBags. Before
+we code on, we therefore define a couple more test cases. The expected
+MoneyBag results use the convenience constructor shown above, initializing
+a MoneyBag from an array.
+<pre><tt>public void testMixedSimpleAdd() {&nbsp;
+&nbsp;&nbsp;&nbsp; // [12 CHF] + [7 USD] == {[12 CHF][7 USD]}&nbsp;
+&nbsp;&nbsp;&nbsp; Money bag[]= { f12CHF, f7USD };&nbsp;
+&nbsp;&nbsp;&nbsp; MoneyBag expected= new MoneyBag(bag);&nbsp;
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(expected, f12CHF.add(f7USD));&nbsp;
+}</tt></pre>
+The other tests follow the same pattern:
+<menu>
+<li>
+testBagSimpleAdd - to add a MoneyBag to a simple Money</li>
+
+<li>
+testSimpleBagAdd - to add a simple Money to a MoneyBag</li>
+
+<li>
+testBagBagAdd - to add two MoneyBags</li>
+</menu>
+Next, we extend our test suite accordingly:
+<pre><tt>public static Test suite() {
+&nbsp;&nbsp;&nbsp; TestSuite suite= new TestSuite();
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testMoneyEquals"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testBagEquals"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testSimpleAdd"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testMixedSimpleAdd"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testBagSimpleAdd"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testSimpleBagAdd"));
+&nbsp;&nbsp;&nbsp; suite.addTest(new MoneyTest("testBagBagAdd"));
+&nbsp;&nbsp;&nbsp; return suite;
+}</tt></pre>
+Having defined the test cases we can start to implement them. The implementation
+challenge here is dealing with all the different combinations of Money
+with MoneyBag. Double dispatch <a href="#Beck, K. Smalltalk Best Practice Patterns,">[2]</a>
+is an elegant way to solve this problem. The idea behind double dispatch
+is to use an additional call to discover the kind of argument we are dealing
+with. We call a method on the argument with the name of the original method
+followed by the class name of the receiver. The add method in Money and
+MoneyBag becomes:
+<pre><tt>class Money implements IMoney {
+&nbsp;&nbsp;&nbsp; public IMoney add(IMoney m) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m.addMoney(this);
+&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; //…
+}</tt></pre>
+
+<pre><tt>class MoneyBag implements IMoney {
+&nbsp;&nbsp;&nbsp; public IMoney add(IMoney m) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m.addMoneyBag(this);
+&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; //…
+}</tt></pre>
+In order to get this to compile we need to extend the interface of IMoney
+with the two helper methods:
+<pre><tt>interface IMoney {
+//…
+&nbsp;&nbsp;&nbsp; IMoney addMoney(Money aMoney);
+&nbsp;&nbsp;&nbsp; IMoney addMoneyBag(MoneyBag aMoneyBag);
+}</tt></pre>
+To complete the implementation of double dispatch, we have to implement
+these methods in Money and MoneyBag. This is the implementation in Money.
+<pre><tt>public IMoney addMoney(Money m) {
+&nbsp;&nbsp;&nbsp; if (m.currency().equals(currency()) )
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Money(amount()+m.amount(), currency());
+&nbsp;&nbsp;&nbsp; return new MoneyBag(this, m);
+}
+
+public IMoney addMoneyBag(MoneyBag s) {
+&nbsp;&nbsp;&nbsp; return s.addMoney(this);
+}</tt></pre>
+Here is the implemenation in MoneyBag which assumes additional constructors
+to create a MoneyBag from a Money and a MoneyBag and from two MoneyBags.
+<pre><tt>public IMoney addMoney(Money m) {
+&nbsp;&nbsp;&nbsp; return new MoneyBag(m, this);
+}
+
+public IMoney addMoneyBag(MoneyBag s) {
+&nbsp;&nbsp;&nbsp; return new MoneyBag(s, this);
+}</tt></pre>
+We run the tests, and they pass. However, while reflecting on the implementation
+we discover another interesting case. What happens when as the result of
+an addition a MoneyBag turns into a bag with only one Money? For example,
+adding -12 CHF to a Moneybag holding 7 USD and 12 CHF results in a bag
+with just 7 USD. Obviously, such a bag should be equal with a single Money
+of 7 USD. To verify the problem let's implement a test case and run it.
+<pre><tt>public void testSimplify() {
+&nbsp;&nbsp;&nbsp; // {[12 CHF][7 USD]} + [-12 CHF] == [7 USD]
+&nbsp;&nbsp;&nbsp; Money expected= new Money(7, "USD");
+&nbsp;&nbsp;&nbsp; Assert.assertEquals(expected, fMB1.add(new Money(-12, "CHF")));
+}</tt></pre>
+When you are developing in this style you will often have a thought and
+turn immediately to writing a test, rather than going straight to the code.
+<p>It comes to no surprise that our test run ends with a red progress bar
+indicating the failure. So we fix the code in MoneyBag to get back to a
+green state.
+<pre><tt>public IMoney addMoney(Money m) {
+&nbsp;&nbsp;&nbsp; return (new MoneyBag(m, this)).simplify();
+}
+
+public IMoney addMoneyBag(MoneyBag s) {
+&nbsp;&nbsp;&nbsp; return (new MoneyBag(s, this)).simplify();
+}
+
+private IMoney simplify() {
+&nbsp;&nbsp;&nbsp; if (fMonies.size() == 1)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (IMoney)fMonies.firstElement()
+&nbsp;&nbsp;&nbsp; return this;
+}</tt></pre>
+Now we run our tests again and voila we end up with green.
+<p>The code above solves only a small portion of the multi-currency arithmetic
+problem. We have to represent different exchange rates, print formatting,
+and the other arithmetic operations, and do it all with reasonable speed.
+However, we hope you can see how you could develop the rest of the objects
+one test at a time- a little test, a little code, a little test, a little
+code.
+<p>In particular, review how in the development above:
+<ul>
+<li>
+We wrote the first test, testSimpleAdd, immediately after we had written
+add(). In general, your development will go much smoother if you write
+tests a little at a time as you develop. It is at the moment that you are
+coding that you are imagining how that code will work. That's the perfect
+time to capture your thoughts in a test.</li>
+
+<li>
+We refactored the existing tests, testSimpleAdd and testEqual, as soon
+as we introduced the common setUp code. Test code is just like model code
+in working best if it is factored well. When you see you have the same
+test code in two places, try to find a way to refactor it so it only appears
+once.</li>
+
+<li>
+We created a suite method, then extended it when we applied Double Dispatch.
+Keeping old tests running is just as important as making new ones run.
+The ideal is to always run all of your tests. Sometimes that will be too
+slow to do 10 times an hour. Make sure you run all of your tests at least
+daily.</li>
+
+<li>
+We created a new test immediately when we thought of the requirement that
+a one element MoneyBag should just return its element. It can be difficult
+to learn to switch gears like this, but we have found it valuable. When
+you are struck by an idea of what your system should do, defer thinking
+about the implementation. Instead, first write the test. Then run it (you
+never know, it might already work). Then work on the implementation.</li>
+</ul>
+
+<h1>
+<a NAME="TestingPractices"></a>Testing Practices</h1>
+Martin Fowler makes this easy for you. He says, "Whenever you are tempted
+to type something into a print statement or a debugger expression, write
+it as a test instead." At first you will find that you have to create a
+new fixtures all the time, and testing will seem to slow you down a little.
+Soon, however, you will begin reusing your library of fixtures and new
+tests will usually be as simple as adding a method to an existing TestCase
+subclass.
+<p>You can always write more tests. However, you will quickly find that
+only a fraction of the tests you can imagine are actually useful. What
+you want is to write tests that fail even though you think they should
+work, or tests that succeed even though you think they should fail. Another
+way to think of it is in cost/benefit terms. You want to write tests that
+will pay you back with information.
+<p>Here are a couple of the times that you will receive a reasonable return
+on your testing investment:
+<ul>
+<li>
+During Development- When you need to add new functionality to the system,
+write the tests first. Then, you will be done developing when the test
+runs.</li>
+
+<li>
+During Debugging- When someone discovers a defect in your code, first write
+a test that will succeed if the code is working. Then debug until the test
+succeeds.</li>
+</ul>
+One word of caution about your tests. Once you get them running, make sure
+they stay running. There is a huge difference between having your suite
+running and having it broken. Ideally, you would run every test in your
+suite every time you change a method. Practically, your suite will soon
+grow too large to run all the time. Try to optimize your setup code so
+you can run all the tests. Or, at the very least, create special suites
+that contain all the tests that might possibly be affected by your current
+development. Then, run the suite every time you compile. And make sure
+you run every test at least once a day: overnight, during lunch, during
+one of those long meetings….
+<h1>
+<a NAME="Conclusion"></a>Conclusion</h1>
+This article only scratches the surface of testing. However, it focuses
+on a style of testing that with a remarkably small investment will make
+you a faster, more productive, more predictable, and less stressed developer.
+<p>Once you've been test infected, your attitude toward development is
+likely to change. Here are some of the changes we have noticed:
+<p>There is a huge difference between tests that are all running correctly
+and tests that aren't. Part of being test infected is not being able to
+go home if your tests aren't 100%. If you run your suite ten or a hundred
+times an hour, though, you won't be able to create enough havoc to make
+you late for supper.
+<p>Sometimes you just won't feel like writing tests, especially at first.
+Don't. However, pay attention to how much more trouble you get into, how
+much more time you spend debugging, and how much more stress you feel when
+you don't have tests. We have been amazed at how much more fun programming
+is and how much more aggressive we are willing to be and how much less
+stress we feel when we are supported by tests. The difference is dramatic
+enough to keep us writing tests even when we don't feel like it.
+<p>You will be able to refactor much more aggressively once you have the
+tests. You won't understand at first just how much you can do, though.
+Try to catch yourself saying, "Oh, I see, I should have designed this thus
+and so. I can't change it now. I don't want to break anything." When you
+say this, save a copy of your current code and give yourself a couple of
+hours to clean up. (This part works best you can get a buddy to look over
+your shoulder while you work.) Make your changes, all the while running
+your tests. You will be surprised at how much ground you can cover in a
+couple of hours if you aren't worrying every second about what you might
+be breaking.
+<p>For example, we switched from the Vector-based implementation of MoneyBag
+to one based on HashTable. We were able to make the switch very quickly
+and confidently because we had so many tests to rely on. If the tests all
+worked, we were sure we hadn't changed the answers the system produced
+at all.
+<p>You will want to get the rest of your team writing tests. The best way
+we have found to spread the test infection is through direct contact. The
+next time someone asks you for help debugging, get them to talk about the
+problem in terms of a fixture and expected results. Then say, "I'd like
+to write down what you just told me in a form we can use." Have them watch
+while you write one little test. Run it. Fix it. Write another. Pretty
+soon they will be writing their own.
+<p>So- give JUnit a try. If you make it better, please send us the changes
+so we can spread them around. Our next article will double click on the
+JUnit framework itself. We will show you how it is constructed, and talk
+a little about our philosophy of framework development.
+<p>We would like to thank Martin Fowler, as good a programmer as any analyst
+can ever hope to be, for his helpful comments in spite of being subjected
+to early versions of JUnit.
+<h1>
+References</h1>
+
+<ol>
+<li>
+<a NAME="Gamma, E., et al. Design Patterns: Elements of"></a>Gamma, E.,
+et al. Design Patterns: Elements of Reusable Object-Oriented Software,
+Addison-Wesley, Reading, MA, 1995</li>
+
+<li>
+<a NAME="Beck, K. Smalltalk Best Practice Patterns,"></a>Beck, K. Smalltalk
+Best Practice Patterns, Prentice Hall, 1996</li>
+</ol>
+
+<hr SIZE=1 WIDTH="100%">
+</body>
+</html>