Test Driven Development
With JUnit & Eclipse




"Never in the field of software development was so much owed by so many to so few lines of code." Martin Fowler in reference to the JUnit Project.

On February 22, 2006, Java Developer's Journal announced that Parasoft Jtest won InfoWorld's 2006 Technology of the Year Award. JTest "automatically generates and executes JUnit tests for instant verification, and allows users to extend these tests." The white paper, Applying a Java Testing Framework [pdf], retrieved from Enerjy Software Integrity on 20 October 2006, provides an interesting discussion of the merits of using unit testing generally and JUnit Testing in Java specifically.

Latest Version of JUnit

This page was initially created when the latest version of JUnit was JUnit3.8.1.

At this time of writing (28 October 2007) JUnit 4.5 has been released. Students are advised to use the latest stable version of JUnit available.

The home of JUnit will be found at http://www.junit.org/

The latest stand alone release (4.5) at time of writing will be found at the sourceforge.net site.

At time of writing, a recent excellent tutorial that students using Eclipse should study is:

Java Unit Testing With JUnit 4.x in Eclipse
[web-html] [web-pdf] [csg-html] [csg-pdf]


JUnit Regression Testing

TaskTopicAssignments

1

Regression Testing

The selective retesting of a software system that has been modified to ensure that any bugs have been fixed and that no other previously working functions have failed as a result of the reparations and that newly added features have not created problems with previous versions of the software. Also referred to as verification testing, regression testing is initiated after a programmer has attempted to fix a recognized problem or has added source code to a program that may have inadvertently introduced errors. It is a quality control measure to ensure that the newly modified code still complies with its specified requirements and that unmodified code has not been affected by the maintenance activity.

- Regression Testing. Retrieved January 8th, 2006, from Wěbopēdia

So What's The Big Deal?

Click here to find out.

The great value of a paradigm in the study of a discipline like Computer Science at the high school level is the scope of it's transference. To implement JUnit Testing in designing and building a Java program is to implement one of the most elegant, powerful paradigms in the social and physical sciences. Whatever your future career, this lesson is relevant!

TaskTopicAssignments

2

JUnit Testing

JUnit JavaDocs Overview

JUnit JavaDocs Tree View

JUnit JavaDocs Index

JUnit Source Code

JUnit Yahoo Group

Junit Executable Zip file

Incorporate JUnit Testing into the IB Dossier in sections:

A2 Criterion For Success
A3 Prototype Solution
D2 Evaluation Solutions

Unit Testing Summary

  1. Download the latest version of JUnit. It is a zipped file. Unzipping the file dumps a folder with a name such as "junit3.8.1". The folder contains:

    README.html  explains contents of downloaded folder & contains links to
    articles that introduce and explain how to implement JUnit.
    junit.jar  a jar file with the JUnit framework and tools
    src.jar  a jar file with the source code of the junit framework
    junit  the source code of the JUnit samples
    samples  sample test cases
    tests  test cases for JUnit itself
    javadoc  javadoc generated documentation
    doc  documentation and accompanying articles

  2. Place both the junit folder and the junit.jar file in a java related folder, but NOT in the the extension directory of your JDK installation. Watch out. Messing up here means that NOTHING will work!

    This crucial step assumes that you understand how to configure a Windows working environment. Read the two page explanation by Ashley Mills, Univeristy of Birminham: Configuring A Windows Working Environment.

    Better explanations in using classpath are found at Java Notes and Java Glossary.

    For example, if you downloaded a junit.zip file and unstalled it to a directory called junit3.8.1, and the path to that junit happened to be c:\Program Files\junit3.8.1, then you would place the following paths in your classpath environmental variable.

    • c:\Program Files\junit3.8.1\junit
    • c:\Program Files\junit3.8.1\junit.jar

    Remember: Do NOT install the junit folder in a JDK directory! Put it somewhere ... anywhere ... else.

    To add paths to the classpath in Windows XP, click: Start --> Control Panel --> System --> Advanced --> Environment Variables --> CLASSPATH --> Edit. There is a classpath variable in both the upper and lower windows of the Environment Variables dialog box. You edit the local variables window, (the upper window of XP's Environment Variables dialog box), not the system window (the lower window of XP's Environment Variables dialog box).

    The following article by Mike Clark explains how to test your installation, but note this. When I ran the all incompassing "junit.samples.AllTests", I kept getting a report of one error out of oodles of executed tests instead of "OK", but my installation has worked without error on the actual examples found in Mike Clark's JUnit Primer 2005 and Keld Hansen's Unit Testing Java Programs 2005 articles below, so I just moved on with the faith that either I will later discover the source of that one error or, it may be, the error was in the reporting and not the installation! (It does happen.)

    Copy the junit folder from this junit executable zip file to your project directory to avoid using environmental variables.

    Do this if setting the classpath doesn't work. Some people don't like messing with the classpath if they can avoid it. It can be frustrating setting environmental variables when things don't work. That is the disadvantage.

    Just put the "junit" folder which holds the byte code (ie: files with the ".class" extension) into the project directory of your program. It is not necessary that your program access the source code (ie: files with the ".java" extension) since it is the *.class files are the exectuable "byte code" files. The byte code files contain the Java machine language that the Java interpreter will convert to native machine language as the program runs.

    There are advantages to placing the path to commonly accessed files in the path and classpath variables. When files are called by a program, they will be automatically located when the path or classpath variable contains a path to those files. Automating the location of the path to a file or folder offers two advantages over making multiple copies of the folder or files:

    1. Save space. You only need one copy of the files.
    2. Save hassle. You need not copy folders or files to the project directory every time you create a new program.

    That said, JUnit's class files are relatively small and copying a directory only takes a few seconds. And let's face it, most programmer's will use JUnit from their IDE anyway where it is "automatically" installed, as with BlueJ and Eclipse.


  3. Do Mike Clark's JUnit Primer 2005 [csg HTML] [web HTML]. This introduction to junit testing is brief and the clearest that I have seen, but still be meticulous in following directions.

    Note the following tips in doing Mike Clark's JUnit Primer 2005.

    • Before even reading the article, download and unzip Clark's ShoppingCart example source code and place it in its own separate directory, such as: c:\src\ShoppingCart

      You will find the following five source code files.

      1. ShoppingCart.java
      2. Product.java
      3. ProductNotFoundException.java
      4. ShoppingCartTest.java
      5. EcommerceTestSuite.java

    • In Mike Clark's article, he compiles and executes his examples from a command prompt, so know this about working from Windows' command line.

      • You can launch a console (command line) window with Start --> Run --> Type either "command" or "cmd" in the "Open" window of the Run dialog box --> click "OK".

      • If you copy a string of text from a normal Windows application (such as examples from Mike Clark's tutorial) into a buffer with [Ctrl-C], you can paste that string after the command line prompt by placing the cursor after the prompt --> right mouse click the title bar of the command line window --> a context sensitive drop-down menu appears --> Edit --> Paste.

      • You can retrieve (repeat) the string of the last command by pressing the [F3] key. (DOS lives on.)

      • You can retrieve prior commands with a "walk through" of all commands used during the current session by pressing the UP and DOWN cursor control arrow keys.

    • Print and study a hard copy of the ShoppingCart source code files. You now have a small but working model of an application's source code with the corresponding JUnit testing code.

    • Mike Clark's articled makes a brief reference to a "factory method". Google it or click here for an explanation.

  4. Do (Java Boutique) Keld Hansen's Unit Testing Java Programs 2005 [web HTML]

    Keld Hansen's article reinforces what we learned in Mike Clark's (above) article. Hansen still works from the command line - as opposed to doing JUnit testing from within an IDE such as Dr. Java, BlueJ or Eclipse.

    Read This If You Prefer To Implement Hansen's Article in TextPad (Rather Than the Command Line) and Place the JUnit folder in the Project Folder Rather Than Setting the ClassPath.

    This particular implementation may be more comfortable for some people as the process is simpler.

    The following directions assume that you are reading and following Hansen's article for explanations.

    1. Create a project folder called "golf" where you will develop code for this program.

    2. Extract the junit bytecode folder from this executable zip file and place it in the "golg" project folder..

    3. Copy the source code for the Course.java class to TextPad. Comment out the package code, "// package hansen.playground;" for this example using TextPad. Save it in the project folder called "golf".

      You should now be able to successfully compile the Course.java source code with <Ctrl><1> but it will not successfully execute after <Ctrl><2> because there is no "public static void main( )" method.

    4. Copy the source code for the TestCourse.java class to TextPad. Again, comment out the package code, "// package hansen.playground;" for this example using TextPad. Save it as well in the project folder called "golf".

      You should now be able to successfully compile the TestCourse.java source code with <Ctrl><1> but the program will still not successfully execute after <Ctrl><2> because there is still no "public static void main( )" method.

      Add a simple "public static void main( )" method as follows and now TestCourse.java will compile and its bytecode (*.class file) will execute.

      public static void main(String args[])
      {
         junit.textui.TestRunner.run(TestCourse.class);
      }

      You will see a successful execution of the command line TestRunner tool, appearing as follows.

    5. Comment out "junit.textui.TestRunner.run(TestCourse.class);" and add " junit.swingui.TestRunner.run(TestCourse.class) ;" to TestCourse.java to run the GUI TestRunner tool.

      public static void main(String args[])
      {
      // junit.textui.TestRunner.run(TestCourse.class);
         junit.swingui.TestRunner.run(TestCourse.class);
      }

      You will see a successful execution of the GUI TestRunner tool, appearing as follows.

    6. Copy the source code for the Round.java class to TextPad. Again, comment out the package code, "// package hansen.playground;" for this example using TextPad. Save it in the project folder called "golf".

      You should now be able to successfully compile the Round.java source code with <Ctrl><1> but, again, there can be no successful execution after <Ctrl><2> because there is no "public static void main( )" method.

    7. Copy the source code for the TestRound.java class to TextPad. Again, comment out the package code, "// package hansen.playground;" for this example using TextPad. Save it as well in the project folder called "golf".

      This test class does indeed have a main method as follows, so it will execute.

      public static void main(String args[])
      {
         junit.textui.TestRunner.run(TestRound.class);
      }

      You will see a successful execution of the command line TestRunner tool, appearing as follows.

    8. Comment out "junit.textui.TestRunner.run(TestRound.class);" and add " junit.swingui.TestRunner.run(TestRound.class) ;" to TestRound.java to run the GUI TestRunner tool.

      public static void main(String args[])
      {
      // junit.textui.TestRunner.run(TestRound.class);
         junit.swingui.TestRunner.run(TestRound.class);
      }

      You will see a successful execution of the GUI TestRunner tool, appearing as follows.

    9. To selectively run only one or two or a few tests instead of all of them, you create and call a test suite. The following static method is added to TestRound.java tests only one method.

      public static Test suite()
      {
         TestSuite suite= new TestSuite();
         suite.addTest(new TestRound("testTiger"));
         return suite;
      }

      To test a second method, just add a second line as follows.

      public static Test suite()
      {
         TestSuite suite= new TestSuite();
         suite.addTest(new TestRound("testTiger"));
         suite.addTest(new TestRound("testThomas"));
         return suite;
      }

      To run all tests, just execute the following Test.suite method instead of the above, passing the entire class into TestSuite.

      public static Test suite()
      {
         return new TestSuite(TestRound.class);
      }

    10. Comment out "junit.textui.TestRunner.run(TestRound.class);" and "junit.swingui.TestRunner.run(TestRound.class) ;" and add "junit.textui.TestRunner.run(suite( ));" to TestRound.java to run the textual TestRunner tool against all the tests listed in the suite.

      public static void main(String args[])
      {
      // junit.textui.TestRunner.run(TestRound.class);
      // junit.swingui.TestRunner.run(TestRound.class);
         junit.textui.TestRunner.run(suite());
      }

      You will see a successful execution of the command line TestRunner tool, appearing as follows.

    11. Of course, you may want to run all tests in all classes at some point, as follows.

      Add a TestSuite method to the TestCourse class similar to that in the TestRound class.

      public static Test suite()
      {
         return new TestSuite(TestCourse.class);
      }

      Create a TestAll.java class that will, well, test all of your classes by calling the TestSuite methods in all of your classes.

      You will see a successful execution of the command line TestRunner tool, appearing as follows.

    The foregoing instructions were intended to assist in achieving the correct code in reading Keld H. Hansen's article in the Java Boutigue entitled, Unit Testing Java Programs. These instructions were not intended to fully explain the rationale and context of the code. For that purpose, the reader is referred to the Hansen article.

    Hansen goes further in clearly introducing the importance of assertion statements as the mechanism that makes JUnit so efficient in automating testing.

    Hansen also introduces us to three implementation of JUnit's TestRunner Tool.

    1.  Command Line:  java junit.textui.TestRunner TestCourse
    2.  AWT Interface:  java junit.awtui.TestRunner TestCourse
    3.  GUI Interface:  java junit.swingui.TestRunner TestCourse

    Hansen introduces some of the most important assertion statements.

    NameUsed For
    assertEquals (a,b) asserts that the two parameters are equal. a and b must be either the same primitive type or both Objects
    assertTrue (boolean) asserts that a given condition is true
    assertNull (Object) asserts that an object is null
    assertSame (Object, Object) asserts that two objects references the same object

    Hansen's tutorial shows that we can choose to run all tests in a single class or only those tests that we select in a static suite() method.

    All Tests RunOnly Tests Selected in suite( ) run
    public static void main(String args[])
    {
        junit.textui.TestRunner.run(TestRound.class);
    }
    public static void main(String args[])
    {
        junit.textui.TestRunner.run(suite());
    }
    public static Test suite()
    {
        TestSuite suite = new TestSuite();
        suite.addTest(new TestRound("testTiger"));
        return suite;
    }
    public static Test suite()
    {
        TestSuite suite = new TestSuite();
        suite.addTest(new TestRound("testTiger"));
        suite.addTest(new TestRound("testThomas"));
        return suite;
    }

    Hansen also shows us code that runs multiple suites of tests from multiple classes by specifying the actual suite( ) of classes that we want to test.

    import junit.framework.*;

    public class TestAll extends TestCase
    {
        public TestAll(String name)
        {
            super(name);
        }
        public static void main(String args[])
        {
            junit.textui.TestRunner.run(suite());
        }

        public static Test suite()
        {
            TestSuite suite = new TestSuite();
            suite.addTest(TestCourse.suite());
            suite.addTest(TestRound.suite());
            return suite;
        }
    }

  5. Read Blaine Simpson's JUnit Howto 2005 [csg HTML] [web HTML] [csg PDF]

    You should now feel comfortable reading this article except for references to "Ant" at the end. Conor MacNeill gives a pretty sound reply to that question in his article, What is Ant? 2003 [csg HTML] [web HTML]

    Blaine poses an "exercise" to solve, but reading this article will make you grateful that you read and implemented code from the above two articles. There is little to gain in his exercise.

  6. You are now ready to inspect version 3.8.1 (2005) of JUnit Javadocs and especially the Assert class. Assert methods throw an AssertionFailedError followed by an appropriate message.

  7. If you open the README.html file found in the unzipped junit folder, you will find the following articles with examples and source code used in the articles. Since these articles are distributed with JUnit itself, we may assume that most users of JUnit are familiar with them. Browse the articles and, if time permits, implement the Money example used in the articles.

  8. Read Ashley J.S Mills' JUnit Testing Utility Tutorial (2005) [csg HTML] [csg pdf] [web HTML]

    Mills illustrates a somewhat more complicated example, hinting at dossier-level complexity.

  9. Read Jasmit Kochhar's JUnit Test Driven Development 2003 [csg HTML no source code] [web HTML includes example source code]

    Kochhar's 2003 article illustrates the simplicity of the private fixture method, setUp( ) which sets up the test fixture. and is called before every test case method, and tearDown( ), that is called after every test case method!

    protected void setUp()
    {
        aProduct = new Product("Product 1", 4, 20.05);
    }

    protected void tearDown()
    {
        aProduct = null;
    }

    If you have read and implemented the foregoing articles and code, this article gives an interesting twist to what you already know. Never underestimate looking at the same material from a slightly different persptective.

    Kochar's article references J. David Varty's JUnit: A Starter Guide [pdf] which uses the famous Money example.

  10. Jamie Scheinblum's Creating JUnit test cases 2002 [csg HTML no source code] [web HTML includes example source code] applies JUnit to Xerces XML parser, a real world application, against a simple XML document.

  11. Alvin Alexander's Working Backwards with JUnit 2002 [csg HTML] [web HTML] from Introduction to Java and OOA/OOD for Web Applications puts JUnit is perspective in relation to various types of testing.

  12. Jim Dixon's JUnit Tutorial 2003 [csg HTML] [web HTML] is a very nice recap of the process.

  13. A brief, clean description of JUnit that should be totally comprehensible at this point: [csg] [web]

TaskTopicAssignments

3

JUnit Testing
With Eclipse

CoffeeMaker.zip

  1. Do LaLiLuna's Eclipse Junit testing tutorial 2005 [csg HTML] [csg pdf] [web HTML]

    This is a brief tutorial which, if you have done the above stand alone JUnit exercises, will appear simple, but it introduces you to the use of JUnit testing within Eclipse with the briefest of code.

    This tutorial gives you the code for a class called Book with an equals( ) method that checks whether the title and price of two books are equal. You are asked to create a separate BookTest class with a testEquals( ) method that tests the equals( ) method in class Book.

    Note that the example code only imported junit.framework.TestCase, but you will have to import all of junit.framework.* when you add the method [ public static Test suite() ] to the BookTest class.

    Click here for source code for Book.java and BookTest.java

    Key Pushes Running This Tutorial In Eclipse
    1. Launch Eclipse.

    2. Identify the workspace directory, such as c:\src\cs33.

    3. Create a project directory for the Book exercise: File --> New --> Project --> Java Project --> Next --> Project Name: BookPrj --> JDK Compliance: 5.0 --> Create separate source output folders --> Finish.

    4. Create a package named for the author's university: laliluna. File --> New --> Package --> Name: laliluna --> Finish

    5. Create a class directory for the Book class: Right mouse click "laliluna" --> New --> Class --> Name: Book --> Finish.

    6. Copy the source code of Book.java: Refer to ComSciGare\Learn JUnit instructions for LaLiLuna's article, "Eclipse JUnit testing tutorial 2005": Left mouse click the link to Book.java --> Open --> File opens in default editor such s NotepPad and TestPad.

    7. Copy source code from default editor less "package de.laliluna.tutorial.junitexample;" --> Note that Book.java sits in the package named, "package laliluna;"

    8. Paste the source code in the Eclipse editor's space for Book.java.

    9. Create a JUnit class (not just a conventional class) directory for the BookTest class: Right mouse click "laliluna" --> New --> JUnit Test Case --> Click "Yes" to add the JUnit library 'JUnit.jar' path to the build path --> Name: BookTest --> Finish.

    10. Copy the source code of BookTest.java: Refer to ComSciGare\Learn JUnit instructions for LaLiLuna's article, "Eclipse JUnit testing tutorial 2005": Left mouse click the link to BookTest.java --> Open --> File opens in default editor such s NotepPad and TestPad.

    11. Copy source code from default editor less "package de.laliluna.tutorial.junitexample;" --> Note that Book.java sits in the package named, "package laliluna;"

    12. Paste the source code in the Eclipse editor's space for BookTest.java.

    13. Change the import statement "import de.laliluna.tutorial.junitexample.Book;" to comply with the actual name of the current package so that it reads, "import laliluna.Book;"

    14. Run the JUnit tests: Click tab of "BookTest.java" --> Right mouse click in editor space of "BookTest.java" --> Run As --> JUnit Test. (Note: You cannot execute the JUnit test class "BookTest.java" as is with "Run as --> As An Application".)

    15. You should observe that the JUnit Tool shows no errors. Indeed, the windows version of the tool shows a confirming green bar across the middle of the GUI for JUnit.


  2. Do McCracken's Getting started with JUnit 2005 (In Eclipse) [csg HTML] [web HTML]

    This very interesting exercise demonstrates that your testing methodology can be very correct, but that JUnit can still report failures when your substantive methodology is incorrect. (Substantive refers to the "substance" of your problem, which may be a physics problem, mathematical or accounting calculation, et cetera.) Here, then, you must direct your attention to working with the substantive problem and not just the testing code.

    Incidently, remember that, when starting a JUnit TestClass in Eclipse, do create a JUnit Test Case class as follows and not an ordinary java class.

    1. Right mouse click the package icon in Package Explorer.
    2. Focus New.
    3. Click JUnit Test Case.

  3. Do Stony Brook's JUnit Testing (With Eclipse) 2005 [csg HTML] [web HTML]

    This tutorial does well in reviewing the procedure of creating JUnit tests in Eclipse with an existing package of source code.

    This tutorial does not provide source code to exercise the instruction.

    A highlight of this tutorial was the reminder that "JUnit framework provides us with several ways to judge if a test has succeeded or failed. Our TestCase object that we have extends Assert which provides the following functionality for testing."

    assertEquals This provides a series of overloads that allows you to test if an actual value matches the expected one.
    assertFalse This provides a series of overloads that allows you to test if an actual value matches the expected one.
    assertNotNull If your method return null in the event of failure use this to check to see if it succeeds.
    assertNotSame If your method is supposed to return an element from a list you can use this to check if the element returned is the one from the actual list.
    assertNull If your method return null in the event of failure use this to check to see if it fails.
    fail Will fail the test, use this in conjunction with conditionals.
    failNotEquals Essentially the same as assertEquals but will fail the test if they arent equal instead of causing an error.
    failNotSame Essentially the same as assertNotSame except instead of causing an error it will cause a failure.

  4. Do Prohorenko's Using JUnit With Eclipse IDE Feb/2004 [csg HTML] [web HTML]

    If you have done all of the above, then this tutorial offers little further about JUnit testing.

    However, this tutorial does categorize JUnit as a developer test, reminding us that there are different types of tests required and used in the process of building excellent software.

    Unit tests These serve to check the correctness of several modules (i.e., classes). If the object needs access to some external data source, like a database, these are simulated with mock objects, but only in cases in which re-creating the actual data source would be difficult in a test environment.
    Customer's tests These are functional, system, and acceptance tests. All of them check the behavior of the system as a whole. In the XP methodology, these tests are written by the customer, given the program skeleton.
    Integration tests These are like a cross between the customer tests and unit tests. Integration tests help test the interaction of several levels of the application. Typically, mock objects are not used in integration testing, which may increase testing time. Also, integration tests often demand the presence of a special test environment, such as a database seeded with test data. Integration tests may also use special external libraries. An example of such a library for the integration of J2EE applications is Cactus. Explanation of these tests is going beyond of this article, and requires much detailed theory information, so you just take it as information that such kind of tests exists.
    Developer's tests These are just tests that developers use to verify whole code, new pieces of code, and/or new functions. For each developer, it is important to generate new tests to check code whenever possible. Organizing these tests can be as important as organizing the code base itself.

  5. Do North Carolina's tutorial Unit Testing in Eclipse Using JUnit 2005 [csg HTML] [web HTML]

    This tutorial should be straight forward by this time. We are reminded: "It is considered a best practice in testing, to separate the test case code from the application code."

    You must unzip the CoffeeMaker.zip file before you can import the CoffeeMaker project into Eclipse.

    To import the CoffeeMaker project into Eclipse: File --> Import --> Existing Projects Into Workspace --> Next --> Select Root Directory and Browse to the directory called CoffeeMaker --> The path to the directory appears in the "Select root directory" dialog window. --> The name "CoffeeMaker" appears in the large, lower "Projects" dialog window. --> Click the adjacent box placing a check mark beside the name "CoffeeMaker" in the "Projects" dialog window. --> Finish --> The CoffeeMaker project should now appear in Eclipse's Package Explorer.

    You are required to create and run an Inventory TestClass with tests on the last three functions of the CoffeeMaker project that will find two bugs in the three functions. Fix the bugs and rerun the JUnit unit tests so that all give the green bar.

  6. Do UBC's excellent tutorial Black Box Testing and JUnit [csg] [web]

TaskTopicAssignments

4

JUnit Testing
of a
Linked List

JUnit Testing is really overkill for a small program, but it shows best with larger, dossier sized programs.

When looking for a JUnit angle with each of the following references, use "Edit --> Find" for "junit".

One example comes from England: [csg] [web]

Example of testing a stack: [csg] [web]

Examples (zipped) of testing a stack, queue, and much else: [csg] [web]

Interesting discussion of black-box testing (user perspective only) versus white-box testing (knowledge of code used to create tests) with linked lists and arrays as examples. [web] and interesting related Powerpoint lecture [csg]

A list of examples of all sorts of code including a sample JUnit Stack Test. [web]


URL:   http://www.comscigate.com/    Last Revised:  December 21-28, 2005