JUnit (at http://junit.org/) is a class library for writing unit tests for Java software.
Unit testing is normally practiced by developers, who write tests of individual program units to check them out before releasing them for inclusion in a larger project. It most naturally corresponds to the testing that students might do, since the focus is on testing the features or individual classes or modules. Other kinds of testing include integration testing, which usually focuses on testing interconnected collections of units to make sure they work together when they are integrated into a whole, functional testing, which usually focuses on ensuring an application meets its requirements, and acceptance testing, which is usually performed by a customer to assess whether a development organization has produced an acceptable (custom) product.
JUnit allows one to write software tests in the form of code, so the tests can be easily executed, and can be re-executed as often as you like with near-zero effort. Phrasing tests in the form of code is more useful than running tests by hand, since it makes the process of executing and managing tests very easy to include in automated build processes, and eliminates human error in conducting these actions.
Basic terms:
The Purpose of Testing: Running software tests can never prove that software is bug-free. The only thing you can determine conclusively through testing in general is when a test fails--then you can prove a bug exists. As a result, many people in the testing community say that the purpose of testing is to demonstrate bugs, so they can be fixed.
Unit tests: software tests of an individual software unit, such as an individual class.
Incremental testing: When a programmer writes individual tests side-by-side with the corresponding code, following the idea of writing a test for each small feature or behavior as that behavior is added to the class(es) being developed. Think "code a little, test a little".
Test-first coding: A variant of incremental testing where the programmer writes the test(s) for each little feature or behavior before writing the corresponding implementation. Normally, that means writing one or more tests that express what you intend to happen after you complete the next small increment of coding--these would naturally be test(s) that fail at first. But these tests express what you are trying to accomplish with your next incremental code addition, and then serve as a check of whether you achieved this goal once you have written the corresponding code. Think "test a little, code a little".
Test class: a
Java class that contains unit tests. For example, the
tests for a class Foo
might be written in a class
called FooTest
, which is a test class.
Test method: Within a test class, each separate "test" the author wishes to perform is phrased as a separate method within the test class. Each test method serves as a "check" for a particular desired feature or behavior.
Test fixture: A test class often sets up a fixed set of initial conditions that serves as the starting point for each test method in the test class. These initial conditions consist of one or more objects that have been configured in any desired state that the programmer thinks is best for running her tests. This initial arrangement of objects that serves as the initial conditions for each test method in a test class is called a test fixture.
Assertions: In order for a test to be effective, it must check something. That is, it most confirm that some desired effect has been achieved. Usually, that means a test will manipulate one or more objects, and then confirm that these objects ended up in the desired state. Each test method uses one or more assertions to express the expected outcome, and also to check that the expected outcome has been achieved.
Test Suite:
A test suite is a collection of tests. Despite the terminology
used in JUnit's documentation, most people think of individual
test methods as tests or test cases, and think
of one or more test classes as a test suite. So it makes
sense to talk about the "test suite for class Foo
"
(maybe just a single test class) as well as the "test suite for
Program Assignment 1" (maybe multiple test classes, covering all
of the classes that make up that assignment).
A Test Passes: If, when a test method is executed, all of its assertions pass, then the test also passes--meaning that all of the behavior checked by the test was achieved.
A Test Fails: If, when a test method is executed, one of its assertions fails, then the test also fails--meaning that at least some part of the behavior checked by the test was not achieved.
"If the bar is green, the code is clean!": Many IDEs summarize JUnit results graphically, using a progress bar that is green if all tests pass, and that turns red as soon as any test being executed fails. This has given rise to this XP phrase, which goes hand-in-hand with the XP idea that code is not added to a project until all tests pass--that is, until "the bar is green".
There are currently three common unit test frameworks in use for Java: JUnit 3, JUnit 4, and TestNG. This page is going to focus on JUnit 3, although JUnit 4 techniques can also be used.
JUnit 3 is the slightly older version of JUnit but the most popular version in many classrooms. For the education market, many introductory textbooks are still using 3.x, so this tutorial will use 3.x examples. Code written for JUnit 3.x will run under JUnit 4, as the newer version includes support for the older tests. There is a separate, official Getting Started page for JUnit v3.8.
JUnit 4 makes use of Java Annotations to simplify the specification of unit tests. The annotations take the place of several conventions that were used in JUnit 3.x testing. JUnit 4 will still execute test cases and suites written using the JUnit 3 conventions. The Getting Started page for JUnit 4 has lots of information on how to use it. You can also use JUnit 4-style annotations and features with your tests when applying the concepts in this tutorial, although the details will be slightly different than the examples shown.
Testing: The Next Generation (TestNG) is a newer framework inspired by JUnit that addresses some of the design limitations of JUnit. We will not be covering TestNG in this tutorial, and many of the features shown in this tutorial will not work with TestNG. IF you use TestNG, you'll have to use somewhat different techniques, so it is not the ideal place for beginners to start. The website for TestNG has documentation and examples on how to use it. We will not cover TestNG but you should be aware of its availability and possible future popularity.