title: @SpringBootTest + @BeforeAll
body: <p>I have a small spring boot app with database and rabbitmq usages.
  So I would like to test with integration test (H2 + apache qpid).</p>
  
  <pre><code>@ExtendWith(SpringExtension.class)
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestSpringConfig.class)
  @TestInstance(TestInstance.Lifecycle.PER_CLASS)
  </code></pre>
  
  <p>As my app expect database and mq Im using @BeforeAll to start it:</p>
  
  <pre><code>@BeforeAll
  public void before() {
      startMessageBroker();
      startDatabase();
  }
  </code></pre>
  
  <p>The problem is that my web app starts before database/mq defined in @BeforeAll. </p>
  
  <p>org.springframework.test.context.junit.jupiter.SpringExtension:</p>
  
  <pre><code>public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor,
          BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback,
          ParameterResolver {
  // ...
      @Override
      public void beforeAll(ExtensionContext context) throws Exception {
          getTestContextManager(context).beforeTestClass();
      }
  // ...
      @Override
      public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
          getTestContextManager(context).prepareTestInstance(testInstance);
      }
  // ...
  </code></pre>
  
  <p>Web app starts in postProcessTestInstance phase and @BeforeAll methods in beforeAll.</p>
  
  <p>org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor:</p>
  
  <pre><code>private void execute(TestDescriptor testDescriptor, C parentContext, ExecutionTracker tracker) {
      Node&lt;C&gt; node = asNode(testDescriptor);
      tracker.markExecuted(testDescriptor);
  
      C preparedContext;
      try {
          preparedContext = node.prepare(parentContext); // 1 &lt;&lt;&lt;
          SkipResult skipResult = node.shouldBeSkipped(preparedContext);
          if (skipResult.isSkipped()) {
              this.listener.executionSkipped(testDescriptor, skipResult.getReason().orElse("&lt;unknown&gt;"));
              return;
          }
      }
      catch (Throwable throwable) {
          rethrowIfBlacklisted(throwable);
          // We call executionStarted first to comply with the contract of EngineExecutionListener
          this.listener.executionStarted(testDescriptor);
          this.listener.executionFinished(testDescriptor, TestExecutionResult.failed(throwable));
          return;
      }
  
      this.listener.executionStarted(testDescriptor);
  
      TestExecutionResult result = singleTestExecutor.executeSafely(() -&gt; {
          C context = preparedContext;
          try {
              context = node.before(context); // 2 &lt;&lt;&lt;
  
              C contextForDynamicChildren = context;
              context = node.execute(context, dynamicTestDescriptor -&gt; {
                  this.listener.dynamicTestRegistered(dynamicTestDescriptor);
                  execute(dynamicTestDescriptor, contextForDynamicChildren, tracker);
              });
  
              C contextForStaticChildren = context;
              // @formatter:off
              testDescriptor.getChildren().stream()
                      .filter(child -&gt; !tracker.wasAlreadyExecuted(child))
                      .forEach(child -&gt; execute(child, contextForStaticChildren, tracker));
              // @formatter:on
          }
          finally {
              node.after(context);
          }
      });
  
      this.listener.executionFinished(testDescriptor, result);
  }
  </code></pre>
  
  <p>See points 1 and 2. There are executions of 'prepare' and then 'before'.</p>
  
  <p>Im not sure is it issue of junit, SpringExtension or Im doing something wrong.
  Any advice?</p>
  
  <blockquote>
    <p>junit-jupiter: 5.0.1 </p>
    
    <p>spring-test: 5.0.0.RELEASE</p>
    
    <p>spring-boot-test: 1.5.8.RELEASE</p>
  </blockquote>