JUnit Changelog

What's new in JUnit 4.10

Sep 30, 2011
  • RuleChain:
  • The RuleChain rule allows ordering of TestRules:
  • public static class UseRuleChain {
  • @Rule
  • public TestRule chain= RuleChain
  • .outerRule(new LoggingRule("outer rule")
  • .around(new LoggingRule("middle rule")
  • .around(new LoggingRule("inner rule");
  • @Test
  • public void example() {
  • assertTrue(true);
  • writes the log
  • starting outer rule
  • starting middle rule
  • starting inner rule
  • finished inner rule
  • finished middle rule
  • finished outer rule
  • TemporaryFolder:
  • `TemporaryFolder#newFolder(String... folderNames)` creates recursively deep temporary folders
  • `TemporaryFolder#newFile()` creates a randomly named new file, and `#newFolder()` creates a randomly named new folder
  • Theories:
  • The `Theories` runner does not anticipate theory parameters that have generic types, as reported by github#64. Fixing this won't happen until `Theories` is moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the necessary machinery to the runner classes, and deprecates a method that only the `Theories` runner uses, `FrameworkMethod`#producesType().
  • The Common Public License that JUnit is released under is now included
  • in the source repository.
  • Bug fixes:
  • Built-in Rules implementations
  • TemporaryFolder should not create files in the current working directory if applying the rule fails
  • TestWatcher and TestWatchman should not call failed for AssumptionViolatedExceptions
  • Javadoc bugs
  • Assert documentation
  • ClassRule
  • Parameterized
  • Parameterized, again
  • Miscellaneous
  • Useless code in RunAfters
  • Parameterized test classes should be able to have `@Category` annotations
  • Error count should be initialized in junit.tests.framework.TestListenerTest
  • AssertionFailedError constructor shouldn't call super with null message
  • Clearer error message for non-static inner test classes
  • Minor changes:
  • Description, Result and Failure are Serializable
  • FailOnTimeout is reusable, allowing for retrying Rules
  • New `ErrorCollector.checkThat` overload, that allows you to specify a reason

New in JUnit 4.9 (Aug 23, 2011)

  • ClassRule:
  • The `ClassRule` annotation extends the idea of method-level Rules,
  • adding static fields that can affect the operation of a whole class. Any
  • subclass of `ParentRunner`, including the standard `BlockJUnit4ClassRunner`
  • and `Suite` classes, will support `ClassRule`s.
  • For example, here is a test suite that connects to a server once before
  • all the test classes run, and disconnects after they are finished:
  • RunWith(Suite.class)
  • SuiteClasses({A.class, B.class, C.class})
  • public class UsesExternalResource {
  • public static Server myServer= new Server();
  • ClassRule
  • public static ExternalResource resource= new ExternalResource() {
  • Override
  • protected void before() throws Throwable {
  • myServer.connect();
  • Override
  • protected void after() {
  • myServer.disconnect();
  • TestRule:
  • In JUnit 4.9, fields that can be annotated with either `Rule` or `ClassRule`
  • should be of type `TestRule`. The old `MethodRule` type, which only made sense
  • for method-level rules, will still work, but is deprecated.
  • Most built-in Rules have been moved to the new type already, in a way that
  • should be transparent to most users. `TestWatchman` has been deprecated,
  • and replaced by `TestWatcher`, which has the same functionality, but implements
  • the new type.
  • Maven support:
  • Maven bundles have, in the past, been uploaded by kind volunteers. Starting
  • with this release, the JUnit team is attempting to perform this task ourselves.
  • LICENSE checked in ###
  • The Common Public License that JUnit is released under is now included
  • in the source repository.
  • Bug fixes:
  • assumeTrue() does not work with expected exceptions
  • Categories + Parameterized
  • In JUnit 4.8.2, the Categories runner would fail to run correctly
  • if any contained test class had a custom Runner with a structure
  • significantly different from the built-in Runner. With this fix,
  • such classes can be assigned one or more categories at the class level,
  • and will be run correctly. Trying to assign categories to methods within
  • such a class will flag an error.
  • ParentRunner filters more than once
  • protected BlockJUnit4ClassRunner#rules method removed from 4.8.2
  • Accidental dependency on Java 6
  • Bad comparison failure message when using assertEquals(String, String)
  • github#227: ParentRunner now assumes that getChildren() returns a modifiable list
  • Minor changes:
  • Backed out unused folder "experimental-use-of-antunit", replaced by
  • bash-based script at build_tests.sh
  • Various Javadoc fixes

New in JUnit 4.8.2 (Aug 23, 2011)

  • Bug fixes:
  • TestSuite(MyTestCase.class) should dynamically detect if MyTestCase is a TestCase

New in JUnit 4.8.1 (Aug 23, 2011)

  • Bug fixes:
  • Category annotations on classes were not honored.

New in JUnit 4.8 (Aug 23, 2011)

  • Categories:
  • From a given set of test classes, the Categories runner runs only the classes and methods that are annotated with either the category given with the IncludeCategory annotation, or a subtype of that category. Either classes or interfaces can be used as categories. Subtyping works, so if you say IncludeCategory(SuperClass.class), a test marked Category({SubClass.class}) will be run.
  • You can also exclude categories by using the @ExcludeCategory annotation
  • Example:
  • public interface FastTests { /* category marker */ }
  • public interface SlowTests { /* category marker */ }
  • public class A {
  • Test
  • public void a() {
  • fail();
  • Category(SlowTests.class)
  • Test
  • public void b() {
  • Category({SlowTests.class, FastTests.class})
  • public class B {
  • Test
  • public void c() {
  • RunWith(Categories.class)
  • IncludeCategory(SlowTests.class)
  • SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
  • public class SlowTestSuite {
  • // Will run A.b and B.c, but not A.a
  • RunWith(Categories.class)
  • IncludeCategory(SlowTests.class)
  • ExcludeCategory(FastTests.class)
  • SuiteClasses( { A.class, B.class }) // Note that Categories is a kind of Suite
  • public class SlowTestSuite {
  • // Will run A.b, but not A.a or B.c
  • Bug fixes:
  • thread safety of Result counting

New in JUnit 4.7 (Aug 23, 2011)

  • Rules:
  • Rules allow very flexible addition or redefinition of the behavior
  • of each test method in a test class. Testers can reuse or extend one of the
  • provided Rules below, or write their own.
  • For more on this feature, see http://www.threeriversinstitute.org/blog/?p=155
  • The TemporaryFolder Rule allows creation of files and folders
  • that are guaranteed to be deleted when the test method finishes
  • (whether it passes or fails):
  • public static class HasTempFolder {
  • Rule
  • public TemporaryFolder folder= new TemporaryFolder();
  • Test
  • public void testUsingTempFolder() throws IOException {
  • File createdFile= folder.newFile("myfile.txt");
  • File createdFolder= folder.newFolder("subfolder");
  • // ...
  • ExternalResource is a base class for Rules (like TemporaryFolder)
  • that set up an external resource before a test (a file, socket, server,
  • database connection, etc.), and guarantee to tear it down afterward:
  • public static class UsesExternalResource {
  • Server myServer = new Server();
  • Rule public ExternalResource resource = new ExternalResource() {
  • Override
  • protected void before() throws Throwable {
  • myServer.connect();
  • Override
  • protected void after() {
  • myServer.disconnect();
  • Test public void testFoo() {
  • new Client().run(myServer);
  • The ErrorCollector Rule allows execution of a test to continue
  • after the first problem is found (for example, to collect _all_ the
  • incorrect rows in a table, and report them all at once):
  • public static class UsesErrorCollectorTwice {
  • Rule
  • public ErrorCollector collector= new ErrorCollector();
  • Test public void example() {
  • collector.addError(new Throwable("first thing went wrong"));
  • collector.addError(new Throwable("second thing went wrong"));
  • Verifier is a base class for Rules like ErrorCollector, which
  • can turn otherwise passing test methods into failing tests if a verification
  • check is failed
  • public static class ErrorLogVerifier() {
  • private ErrorLog errorLog = new ErrorLog();
  • Rule
  • public MethodRule verifier = new Verifier() {
  • Override public void verify() {
  • assertTrue(errorLog.isEmpty());
  • Test public void testThatMightWriteErrorLog() {
  • // ...
  • TestWatchman is a base class for Rules that take note
  • of the testing action, without modifying it.
  • For example, this class will keep a log of each passing and failing
  • test:
  • public static class WatchmanTest {
  • private static String watchedLog;
  • Rule
  • public MethodRule watchman= new TestWatchman() {
  • Override
  • public void failed(Throwable e, FrameworkMethod method) {
  • watchedLog+= method.getName() + " "
  • + e.getClass().getSimpleName() + "\n";
  • Override
  • public void succeeded(FrameworkMethod method) {
  • watchedLog+= method.getName() + " " + "success!\n";
  • Test
  • public void fails() {
  • fail();
  • Test
  • public void succeeds() {
  • The TestName Rule makes the current test name available inside test methods:
  • public class NameRuleTest {
  • Rule public TestName name = new TestName();
  • Test public void testA() {
  • assertEquals("testA", name.getMethodName());
  • Test public void testB() {
  • assertEquals("testB", name.getMethodName());
  • The Timeout Rule applies the same timeout to all test methods in a class:
  • public static class HasGlobalTimeout {
  • public static String log;
  • Rule public MethodRule globalTimeout = new Timeout(20);
  • Test public void testInfiniteLoop1() {
  • log+= "ran1";
  • for(;;) {}
  • Test public void testInfiniteLoop2() {
  • log+= "ran2";
  • for(;;) {}
  • The ExpectedException Rule allows in-test specification
  • of expected exception types and messages:
  • public static class HasExpectedException {
  • Rule
  • public ExpectedException thrown= ExpectedException.none();
  • Test
  • public void throwsNothing() {
  • Test
  • public void throwsNullPointerException() {
  • thrown.expect(NullPointerException.class);
  • throw new NullPointerException();
  • Test
  • public void throwsNullPointerExceptionWithMessage() {
  • thrown.expect(NullPointerException.class);
  • thrown.expectMessage("happened?");
  • thrown.expectMessage(startsWith("What"));
  • throw new NullPointerException("What happened?");
  • Timeouts:
  • Tests that time out now show the stack trace of the test thread.
  • Matchers:
  • Due to typing incompatibilities, JUnit is still including the 1.1 release
  • of hamcrest. This is not a change from 4.6, but is a change from
  • pre-beta releases of 4.7.
  • Docs:
  • Javadocs now link to online JDK javadocs (bug 2090230)
  • Parameterized runner javadocs improved (bug 2186792)
  • Fixed Javadoc code sample for AfterClass (2126279)
  • Fixed Javadoc for assertArraysEqual(float[], float[])
  • Bug fixes:
  • Fixed: BaseTestRunner.getTest() requires class to extend TestCase
  • Fixed: Suite does not allow for inheritance in annotations (2783118)
  • Fixed: ParallelComputer skipped tests that took longer than 2 seconds

New in JUnit 4.6 (Aug 23, 2011)

  • Max:
  • JUnit now includes a new experimental Core, MaxCore. MaxCore remembers the results of previous test runs in order to run new tests out of order. MaxCore prefers new tests to old tests, fast tests to slow tests, and recently failing tests to tests that last failed long ago.
  • Comparing double arrays:
  • Arrays of doubles can be compared, using a delta allowance for equality:
  • @Test
  • public void doubleArraysAreEqual() {
  • assertArrayEquals(new double[] {1.0, 2.0}, new double[] {1.0, 2.0}, 0.01);
  • Filter.matchDescription API
  • Since 4.0, it has been possible to run a single method using the Request.method API. In 4.6, the filter that implements this is exposed as Filter.matchDescription.
  • Documentation:
  • A couple classes and packages that once had empty javadoc have been doc'ed.
  • Added how to run JUnit from the command line to the cookbook.
  • junit-4.x.zip now contains build.xml
  • Bug fixes:
  • Fixed overly permissive @DataPoint processing
  • Fixed bug in test counting after an ignored method

New in JUnit 4.5 (Aug 23, 2011)

  • Installation:
  • We are releasing junit-4.6.jar, which contains all the classes necessary to run JUnit, and junit-dep-4.6.jar, which leaves out hamcrest classes, for developers who already use hamcrest outside of JUnit.
  • Basic JUnit operation:
  • JUnitCore now more often exits with the correct exit code (0 for success, 1 for failure)
  • Badly formed test classes (exceptions in constructors, classes without tests, multiple constructors, Suite without @SuiteClasses) produce more helpful error messages
  • Test classes whose only test methods are inherited from superclasses now run.
  • Optimization to annotation processing can cut JUnit overhead by more than half on large test classes, especially when using Theories. [Bug 1796847]
  • A failing assumption in a constructor ignores the class
  • Correct results when comparing the string "null" with potentially null values. [Bug 1857283]
  • Annotating a class with @RunWith(JUnit4.class) will always invoke the default JUnit 4 runner in the current version of JUnit. This default changed from JUnit4ClassRunner in 4.4 to BlockJUnit4ClassRunner in 4.5 (see below), and may change again.
  • Extension:
  • BlockJUnit4Runner is a new implementation of the standard JUnit 4 test class functionality. In contrast to JUnit4ClassRunner (the old implementation):
  • BlockJUnit4Runner has a much simpler implementation based on Statements, allowing new operations to be inserted into the appropriate point in the execution flow.
  • BlockJUnit4Runner is published, and extension and reuse are encouraged, whereas JUnit4ClassRunner was in an internal package, and is now deprecated.
  • ParentRunner is a base class for runners that iterate over a list of "children", each an object representing a test or suite to run. ParentRunner provides filtering, sorting, @BeforeClass, @AfterClass, and method validation to subclasses.
  • TestClass wraps a class to be run, providing efficient, repeated access to all methods with a given annotation.
  • The new RunnerBuilder API allows extending the behavior of Suite-like custom runners.
  • AssumptionViolatedException.toString() is more informative
  • Extra Runners:
  • Parameterized.eachOne() has been removed
  • New runner Enclosed runs all static inner classes of an outer class.
  • Theories:
  • @Before and @After methods are run before and after each set of attempted parameters on a Theory, and each set of parameters is run on a new instance of the test class.
  • Exposed API's ParameterSignature.getType() and ParameterSignature.getAnnotations()
  • An array of data points can be introduced by a field or method marked with the new annotation @DataPoints
  • The Theories custom runner has been refactored to make it faster and easier to extend

New in JUnit 4.4 (Aug 23, 2011)

  • This release contains other bug fixes and new features. Among them:
  • Annotated descriptions
  • Runner UIs, Filters, and Sorters operate on Descriptions of test methods and test classes. These Descriptions now include the annotations on the original Java source element, allowing for richer display of test results, and easier development of annotation-based filters.
  • Bug fix (1715326): assertEquals now compares all Numbers using their native implementation of equals. This assertion, which passed in 4.3, will now fail:
  • assertEquals(new Integer(1), new Long(1));
  • Non-integer Numbers (Floats, Doubles, BigDecimals, etc), which were compared incorrectly in 4.3, are now fixed.
  • assertEquals(long, long) and assertEquals(double, double) have been re-introduced to the Assert class, to take advantage of Java's native widening conversions. Therefore, this still passes:
  • assertEquals(1, 1L);
  • The default runner for JUnit 4 test classes has been refactored. The old version was named TestClassRunner, and the new is named JUnit4ClassRunner. Likewise, OldTestClassRunner is now JUnit3ClassRunner. The new design allows variations in running individual test classes to be expressed with fewer custom classes. For a good example, see the source to org.junit.experimental.theories.Theories.
  • The rules for determining which runner is applied by default to a test class have been simplified:
  • If the class has a @RunWith annotation, the annotated runner class is used.
  • If the class can be run with the JUnit 3 test runner (it subclasses TestCase, or contains a public static Test suite() method), JUnit38ClassRunner is used.
  • Otherwise, JUnit4ClassRunner is used.
  • This default guess can always be overridden by an explicit @RunWith(JUnit4ClassRunner.class) or @RunWith(JUnit38ClassRunner.class) annotation.
  • The old class names TestClassRunner and OldTestClassRunner remain as deprecated.
  • Bug fix (1739095): Filters and Sorters work correctly on test classes that contain a suite method like:
  • public static junit.framework.Test suite() { return new JUnit4TestAdapter(MyTest.class); }
  • Bug fix (1745048): @After methods are now correctly called after a test method times out.

New in JUnit 4.3.1 (Aug 23, 2011)

  • Bug fix: 4.3 introduced a bug that caused a NullPointerException when comparing a null reference to a non-null reference in assertEquals. This has been fixed.
  • Bug fix: The binary jar for 4.3 accidentally included the tests and sample code, which are now removed for a smaller download, but, as always, available from the full zip.

New in JUnit 4.3 (Aug 23, 2011)

  • Changes in array equality. Using assertEquals to compare array contents is now deprecated. In the future, assertEquals will revert to its pre-4.0 meaning of comparing objects based on Java's Object.equals semantics. To compare array contents, use the new, more reliable Assert.assertArrayEquals methods.
  • The @Ignore annotation can now be applied to classes, to ignore the entire class, instead of individual methods.
  • Originally, developers who wanted to use a static suite() method from JUnit 3.x with a JUnit 4.x runner had to annotate the class with @RunWith(AllTests.class). In the common case, this requirement has been removed. However, when such a class is wrapped with a JUnit4TestAdapter (which we believe is rare), the results may not be as expected.
  • Improved error messages for array comparison("arrays first differed at element [1][0]")
  • Bug fix: Inaccessible base class is caught at test construction time.
  • Bug fix: Circular suites are caught at test construction time.
  • Bug fix: Test constructors that throw exceptions are reported correctly.
  • For committers and extenders
  • Sources now are in a separate "src" directory (this means a big break in the CVS history)
  • Improved documentation in Request, RunWith

New in JUnit 4.2 (Aug 23, 2011)

  • Bug fix: Inaccessible base class is caught at test construction time.
  • Bug fix: Circular suites are caught at test construction time.
  • Improved error messages for array comparison("arrays first differed at element [1][0]")
  • Test constructors that throw exceptions are reported correctly.

New in JUnit 4.1 (Aug 23, 2011)

  • Bug fix: listeners now get a correct test running time, rather than always being told 0 secs.
  • The @RunWith annotation is now inherited by subclasses: all subclasses of an abstract test class will be run by the same runner.
  • The build script fails if the JUnit unit tests fail
  • The faq has been updated
  • Javadoc has been improved, with more internal links, and package descriptions added (Thanks, Matthias Schmidt!)
  • An acknowledgements.txt file has been created to credit outside contributions
  • The Enclosed runner, which runs all of the static inner classes of a given class, has been added to org.junit.runners.

New in JUnit 4.0 (Aug 23, 2011)

  • The architecture of JUnit 4.0 is a substantial departure from that of earlier releases. Instead of tagging test classes by subclassing junit.framework.TestCase and tagging test methods by starting their name with "test", you now tag test methods with the @Test annotation.