[java] Junit - run set up method once

I set up a class with a couple of tests and rather than using @Before I would like to have a setup method that executes only once before all tests. Is that possible with Junit 4.8?

This question is related to java junit

The answer is


If you don't want to force a declaration of a variable that is set and checked on each subtest, then adding this to a SuperTest could do:

public abstract class SuperTest {

    private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
    protected final boolean initialized() {
        final boolean[] absent = {false};
        INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
            return absent[0] = true;
        });
        return !absent[0];
    }
}



public class SubTest extends SuperTest {
    @Before
    public void before() {
        if ( super.initialized() ) return;

         ... magic ... 
    }

}

Edit: I just found out while debugging that the class is instantiated before every test too. I guess the @BeforeClass annotation is the best here.

You can set up on the constructor too, the test class is a class after all. I'm not sure if it's a bad practice because almost all other methods are annotated, but it works. You could create a constructor like that:

public UT () {
    // initialize once here
}
@Test
// Some test here...

The ctor will be called before the tests because they are not static.


Use Spring's @PostConstruct method to do all initialization work and this method runs before any of the @Test is executed


JUnit 5 @BeforeAll can be non static provided the lifecycle of the test class is per class, i.e., annotate the test class with a @TestInstance(Lifecycle.PER_CLASS) and you are good to go


My dirty solution is:

public class TestCaseExtended extends TestCase {

    private boolean isInitialized = false;
    private int serId;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        if(!isInitialized) {
            loadSaveNewSerId();
            emptyTestResultsDirectory();
            isInitialized = true;
        }
    }

   ...

}

I use it as a base base to all my testCases.


Try this solution: https://stackoverflow.com/a/46274919/907576 :

with @BeforeAllMethods/@AfterAllMethods annotation you could execute any method in Test class in an instance context, where all injected values are available.


JUnit 5 now has a @BeforeAll annotation:

Denotes that the annotated method should be executed before all @Test methods in the current class or class hierarchy; analogous to JUnit 4’s @BeforeClass. Such methods must be static.

The lifecycle annotations of JUnit 5 seem to have finally gotten it right! You can guess which annotations available without even looking (e.g. @BeforeEach @AfterAll)


You can use the BeforeClass annotation:

@BeforeClass
public static void setUpClass() {
    //executed only once, before the first test
}

I solved this problem like this:

Add to your Base abstract class (I mean abstract class where you initialize your driver in setUpDriver() method) this part of code:

private static boolean started = false;
static{
    if (!started) {
        started = true;
        try {
            setUpDriver();  //method where you initialize your driver
        } catch (MalformedURLException e) {
        }
    }
}

And now, if your test classes will extends from Base abstract class -> setUpDriver() method will be executed before first @Test only ONE time per run.


When setUp() is in a superclass of the test class (e.g. AbstractTestBase below), the accepted answer can be modified as follows:

public abstract class AbstractTestBase {
    private static Class<? extends AbstractTestBase> testClass;
    .....
    public void setUp() {
        if (this.getClass().equals(testClass)) {
            return;
        }

        // do the setup - once per concrete test class
        .....
        testClass = this.getClass();
    }
}

This should work for a single non-static setUp() method but I'm unable to produce an equivalent for tearDown() without straying into a world of complex reflection... Bounty points to anyone who can!