Search code examples
testingjunit5

Before/after parametrized test in JUnit5


I haven't been able to find a way how to run a custom method before and after a parametrized test.

Do you know if there is a way for JUnit 5?

Something like I saw for JUnit 4: https://junit.org/junit4/javadoc/4.13/org/junit/runners/Parameterized.BeforeParam.html

Edit: I would need something like this:

class BeforeAfterParameterizedTest {

    @BeforeParametrizedTest("test")
    void setUp() {
        System.out.println("invoke custom method before parameterized test");
    }

    @ParameterizedTest
    @ValueSource(strings = {"foo", "bar"})
    void test(String s) {
        System.out.println(s);
    }

    @AfterParametrizedTest("test")
    void tearDown() {
        System.out.println("invoke custom method after parameterized test");
    }

}

With output:

invoke custom method before parameterized test 
foo
bar
invoke custom method after parameterized test

Solution

  • Lifecycle methods are also executed for parameterized tests, so you can invoke your custom method(s) in @BeforeEach/@AfterEach:

    class BeforeAfterParameterizedTest {
    
        @BeforeEach
        void setUp() {
            System.out.println("invoke custom method before each parameterized test");
        }
    
        @ParameterizedTest
        @ValueSource(strings = {"foo", "bar"})
        void test(String s) {
            System.out.println(s);
        }
    
        @AfterEach
        void tearDown() {
            System.out.println("invoke custom method after each parameterized test");
        }
    
    }
    

    Output:

    invoke custom method before each parameterized test
    foo
    invoke custom method after each parameterized test
    invoke custom method before each parameterized test
    bar
    invoke custom method after each parameterized test
    

    EDIT: Given your comment:

    […] I need my custom method to be executed only once before all and after all runs of the parametrized test, so from your example I would need output: invoke custom method before all parameterized test foo bar invoke custom method after all parameterized test

    You can use @BeforeAll and @AfterAll instead:

    class BeforeAfterParameterizedTest {
    
        @BeforeAll
        static void setUpOnce() {
            System.out.println("invoke custom method before all parameterized tests");
        }
    
        @ParameterizedTest
        @ValueSource(strings = {"foo", "bar"})
        void test(String s) {
            System.out.println(s);
        }
    
        @AfterAll
        static void tearDownOnce() {
            System.out.println("invoke custom method after all parameterized tests");
        }
    
    }
    

    Output:

    invoke custom method before all parameterized tests
    foo
    bar
    invoke custom method after all parameterized tests
    

    If your test class contains other tests you don't want the custom method to be executed for, you can wrap the parameterized test and the setup / teardown methods in a nested test. (Note that you need Java 16+ to have static methods in inner classes, see JEP 395.)