Continuing test execution in junit4 even when one of the asserts fails

后端 未结 6 1214
无人及你
无人及你 2020-12-02 16:55

I have my existing framework built up using Jfunc which provides a facility to continue exection even when one of the asserts in the test case fails. Jfunc uses junit 3.x f

相关标签:
6条回答
  • 2020-12-02 17:07

    You can do this using an ErrorCollector rule.

    To use it, first add the rule as a field in your test class:

    public class MyTest {
        @Rule
        public ErrorCollector collector = new ErrorCollector();
    
        //...tests...
    }
    

    Then replace your asserts with calls to collector.checkThat(...).

    e.g.

    @Test
    public void myTest() {
        collector.checkThat("a", equalTo("b"));
        collector.checkThat(1, equalTo(2));
    }
    
    0 讨论(0)
  • 2020-12-02 17:07

    Use try/finally blocks. This worked in my case:

    ...
    try {
        assert(...)
    } finally {
        // code to be executed after assert
    }
    ...
    
    0 讨论(0)
  • 2020-12-02 17:07

    Try - catch, in "try" use the assertion, in "catch" add the possible error to collection. Then throw the exception at the end of test, in tearDown(). So if there will be fail/error in assert, it will be catched and test will continue. (The collection in example is static, you can also make new instance in setUp() for each @Test)

        public static List<String> errors = new ArrayList<>();
    
    
        try {
            //some assert...
        }
        catch (AssertionError error) {
            errors.add(error.toString());
        }
    
    
    
        @After
        public void tearDown() {
    
            try {
                if (!errors.isEmpty()) {
                    throw new AssertionError(errors);
                }
            }
            finally {
                //empty list because it's static, alternatively make instance for each test in setUp()
                errors.clear();
            }
        }
    
    0 讨论(0)
  • 2020-12-02 17:12

    You can also use assertj - soft assertion

    @Test
    public void testCollectErrors(){
       SoftAssertions softly = new SoftAssertions();
       softly.assertThat(true).isFalse();
       softly.assertThat(false).isTrue();
       // Don't forget to call SoftAssertions global verification !
       softly.assertAll();
    }
    

    Also exist other way to use it without manually invoke softly.assertAll();

    1. with rule
    2. with autoclosable
    3. Using the static assertSoftly method
    0 讨论(0)
  • 2020-12-02 17:20

    I use the ErrorCollector too but also use assertThat and place them in a try catch block.

    import static org.junit.Assert.*;
    import static org.hamcrest.Matchers.*;
    
    @Rule
    public ErrorCollector collector = new ErrorCollector();
    
    @Test
    public void calculatedValueShouldEqualExpected() {
        try {
            assertThat(calculatedValue(), is(expected));
        } catch (Throwable t) {
            collector.addError(t);
            // do something
        }
    }
    
    0 讨论(0)
  • 2020-12-02 17:29

    Another option is the observable pattern in conjunction with lambda expressions. You can use something like the above.

    public class MyTestClass {
    
        private final List<Consumer<MyTestClass>> AFTER_EVENT = new ArrayList<>();
    
        @After
        public void tearDown() {
            AFTER_EVENT.stream().forEach(c -> c.accept(this));
        }
    
        @Test
        public void testCase() {
            //=> Arrange
            AFTER_EVENT.add((o) -> {
                // do something after an assertion fail.
            }));
    
            //=> Act
    
            //=> Assert
            Assert.assertTrue(false);
        }
    }
    
    0 讨论(0)
提交回复
热议问题