| <!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<Object> collection; |
| |
| @Before |
| public void setUp() { |
| collection = new ArrayList<Object>(); |
| } |
| |
| @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 <test class name> |
| </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> |
| <property name="src" value="./src" /> |
| <property name="lib" value="./lib" /> |
| <property name="classes" value="./classes" /> |
| <property name="test.class.name" value="com.xyz.MyTestSuite" /> |
| </code></pre> |
| </div> |
| </li> |
| <li> |
| <p> |
| Set up the CLASSPATH to be used by JUnit: |
| </p> |
| <div> |
| <pre><code> |
| <path id="test.classpath"> |
| <pathelement location="${classes}" /> |
| <pathelement location="/path/to/junit.jar" /> |
| <fileset dir="${lib}"> |
| <include name="**/*.jar"/> |
| </fileset> |
| </path> |
| </code></pre> |
| </div> |
| </li> |
| <li> |
| <p> |
| Define the Ant task for running JUnit: |
| </p> |
| <div> |
| <pre><code> |
| <target name="test"> |
| <junit fork="yes" haltonfailure="yes"> |
| <test name="${test.class.name}" /> |
| <formatter type="plain" usefile="false" /> |
| <classpath refid="test.classpath" /> |
| </junit> |
| </target> |
| </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> |
| <property name="test.reports" value="./reports" /> |
| </code> |
| </div> |
| </li> |
| <li> |
| <p> |
| Define the Ant task for running JUnit and generating reports: |
| </p> |
| <div> |
| <pre><code> |
| <target name="test-html"> |
| <junit fork="yes" printsummary="no" haltonfailure="no"> |
| <batchtest fork="yes" todir="${test.reports}" > |
| <fileset dir="${classes}"> |
| <include name="**/*Test.class" /> |
| </fileset> |
| </batchtest> |
| <formatter type="xml" /> |
| <classpath refid="test.classpath" /> |
| </junit> |
| |
| <junitreport todir="${test.reports}"> |
| <fileset dir="${test.reports}"> |
| <include name="TEST-*.xml" /> |
| </fileset> |
| <report todir="${test.reports}" /> |
| </junitreport> |
| </target> |
| </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 "sees" |
| 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 |
| "down" 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 "sees" 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 "proper" 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> |
| <javac srcdir="${src}" destdir="${build}" debug="on" /> |
| </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> |
| <junit printsummary="yes" haltonfailure="yes"> |
| ... |
| <batchtest fork="yes"> |
| <fileset dir="${src.dir}"> |
| <include name="**/*Test.java" /> |
| <include name="**/Test*.java" /> |
| </fileset> |
| </batchtest> |
| </junit> |
| </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> |