JUnit 5: Specify execution order for nested tests
Asked Answered
G

2

9

Is it possible to execute several nested tests in between of some other tests with a fixed execution order?

E.g.

@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(OrderAnnotation.class)
class MyTest {

    private State state = State.ZERO;

    @Test
    @Order(1)
    public void step1() throws IOException {
        state = State.ONE;
    }

    @Order(2)  // sth like this, however this annotation isn't allowed here
    @Nested
    class WhileInStateOne {

        @Test
        public void step2a {
            Assumptions.assumeTrue(state == State.ONE);

            // test something
        }

        @Test
        public void step2b {
            Assumptions.assumeTrue(state == State.ONE);

            // test something else
        }

    }

    @Test
    @Order(3)
    public void step3() throws IOException {
        state = State.THREE;
    }

}

I know, that unit tests should in general be stateless, however in this case I can save a lot of execution time if I can reuse the state in a fixed order.

Grabble answered 2/4, 2019 at 13:30 Comment(4)
You shouldn´t care about the execution time. Let them run on your pipeline automatically and skip it on LDEV - but you shouldn´t run them in order. That´s a hard break.Argile
I suspected comments like this, that's why I wrote that I am aware of the fact that test should not have a state. But there are exceptions and I deliberately broke this "rule" as in my scenario this makes sense (it is more of an integration test anyway). I don't want a fundamental debate, I just want to know how to achieve what I have asked ;-)Grabble
The documentation shows that nested tests does support ordering. So use it there, too. So your test nr 3 would be 5 and nested tests are Nr 3+4.Argile
tried it, but tests in the nested class are still executed after the tests from outer classesGrabble
M
12

Tests in nested classes are always executed after tests in the enclosing class. That cannot be changed.

Methods in the same class can be ordered as follows:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class) 
public class TestCode { 
  
    @Test
    @Order(1) 
    public void primaryTest() 
    {  
    } 
      
    @Test
    @Order(2) 
    public void secondaryTest() 
    { 
    } 
} 

Nested inner test classes can be ordered as follows:

 @TestClassOrder(ClassOrderer.OrderAnnotation.class)
 class OrderedNestedTests {

     @Nested
     @Order(1)
     class PrimaryTests {
          // @Test methods ...
     }

     @Nested
     @Order(2)
     class SecondaryTests {
        // @Test methods ...
     }

}

Monetary answered 2/4, 2019 at 20:18 Comment(5)
Thanks for the clear answer. Any chance this will change eventually?Grabble
You're welcome. No, we (the JUnit Team) have no plans of mixing the execution order of tests between nested test classes and their enclosing classes, simply because that would violate the entire design principles of nested containers.Monetary
So what happens when you have several @Nested tests? What is the order? How do you make the order predictive? AFAIK nested tests are there to organize your test suite. So for ex, you'd refactor a large test class (having the Order annotation on all tests) into several nested test classes but if you can't control the order of the nested tests then you can't do this refactoring since you're going to loose the order. ThxRinderpest
@VincentMassol you can control the order of the execution of nested classes since 5.8.0. Take a look at the release notes, 2nd point: junit.org/junit5/docs/5.8.0/release-notes/… Issue in GitHub: github.com/junit-team/junit5/issues/2699Carissacarita
Absolutely needed, today, the ability to order nested test classes but didn't care about the order in which their tests were executed. Glad to see it is supported!Inhuman
S
1

You can now use @TestClassOrder(ClassOrderer.OrderAnnotation.class) on your main class.

Samy answered 5/3 at 15:48 Comment(1)
This comment is identical to your answer but provides a lot more detail.Severance

© 2022 - 2024 — McMap. All rights reserved.