Skip to content

Latest commit

 

History

History
109 lines (90 loc) · 4.3 KB

README.md

File metadata and controls

109 lines (90 loc) · 4.3 KB

junit4-testing

a lightweight collection of utilities based on JUnit 4

Build Status

Maven coordinates

Just add this to your dependencies:

<dependency>
    <groupId>net.thimmwork</groupId>
    <artifactId>junit4-testing</artifactId>
    <version>2.0</version>
</dependency>

available at maven central.

LifecycleRule

The LifecycleRule interface allows to wrap @BeforeClass, @Before, @After, @AfterClass behavior and more in a single class.

This can be useful when setting up the test environment is expensive and it's easier to reset a subset of the environment between test methods instead of shutting down and setting up the whole environment.

Usage Example

Imagine a test database you want to initialize once (create schema). Additionally, before each test you want to reset your initial data. And after each test, you want to truncate a few tables with dynamic data.

With LifecycleRule, you can write a class like this:

public class TestDatabase implements LifecycleRule {
    @Override
    public void beforeClass(Description description) {
        createSchema();
    }

    @Override
    public void before(Description description) {
        resetInitialData();
    }

    @Override
    public void after(Description description) {
        clearDynamicData();
    }

    @Override
    public void afterClass(Description description) {
        dropSchema();
    }
}

You can bind this TestDatabase to the lifecycle of your test class by this line:

@ClassRule @Rule public static LifecycleRule DATABASE = new TestDatabase();

So if you want to use your TestDatabase in several test classes, you only need a single line of code in each class.

Note that the field has to be static and annotated with both @ClassRule and @Rule annotations due to the JUnit4 mechanisms used under the hood.

Also note that - thanks to composition - your test classes do not need to inherit a super class. This way you can write integration tests that combine multiple environments.

additional lifecycle methods

In addition to the above before/after methods, you can use the methods onMethodSuccess and onMethodFailure to execute code dependent on the test result:

@Override
public void onMethodSuccess(Description) {
    clearEventLog();
}

@Override
public void onMethodFailure(Description) {
    exportSnapshotForErrorAnalysis();
}

before/after Suite

To call methods before/after a Suite, add a static field to your suite and annotate it with @ClassRule like so:

@RunWith(Suite.class)
@SuiteClasses({MyTestCase1.class, MyTestCase2.class})
public class TestSuite {
    @ClassRule public static LifecycleRule RULE = new MySuiteLifecycle();
}

In your test classes you can access the same instance of your Lifecycle by referencing the static field:

public class MyTestCase1 {
    @ClassRule @Rule public static LifecycleRule RULE = TestSuite.RULE;
}

LifecycleRule looks at child descriptions to detect suite hooks from class hooks. Usually you have a structure like

Suite
\- Class
   \- Method

However, if you have nested tests, this detection may not work for you. In this case, you may have to override the detection mechanism in LifecycleRule#isSuite() and/or LifecycleRule#isClass().

FlexiScope

FlexiScope enables to to perform expensive tasks like starting/stopping a database or initializing/resetting state only once per test suite or per test class, which ever you choose to run. It combines beforeSuite/afterSuite with beforeClass/afterClass and remembers which was used.

So if you run the suite, FlexiScope will start the database only once and reuse the same instance for each test class. After each test class the database continues to run. And only after all tests in the suite completed, the database is shut down. If you run a single test class, FlexiScope detects that it is running outside the suite scope and will start and stop the database before/after the test class.

This way you don't have to sacrifice quick test result feedback for fast test suites. FlexiScope gives you the best of both worlds.

Check out FlexiScopeSuiteTest to see an example. .