运行 整个套件时 IntelliJ / Springboot 中的奇怪测试用例失败 - 自行成功

Odd Test Case Failure in IntelliJ / Springboot when Running Entire Suite - Succeeds by Itself

当我在 IntelliJ 中 运行 我的测试用例套件时,我有一个失败的 junit 测试用例。当 运行 独立时,相同的测试用例成功,或者在class。它甚至 运行s 在其他 classes 的其他测试中成功。但是,当我 运行 整套 651 测试时,这 1 个测试失败了

此外,当我 运行 Maven 中的测试用例套件(即 - maven 清理、安装)时,整个套件 运行s 成功。

一种似乎有效的解决方法是在 运行 配置中将分叉模式设置为“Class”。

但是,fork 配置导致测试套件 运行 变慢,我想了解为什么会发生这种情况。失败的测试如下...

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes=MyApplication.class)
class AssetRepositoryTest {

    ....other tests....

    @Transactional
    @Test @DirtiesContext
    void delete_allByAppUser() {
        int deleteCount = assetRepository.deleteAllByAppUser(mainTestAppUser);
        assertEquals(2, deleteCount);
    }

    ....more tests....
}

当测试执行时,Springboot 启动,用一些数据创建 H2 数据库,然后当测试结束时,数据库被删除。该测试旨在测试 JPA 存储库 class。直到最近它一直运行良好,我已经有一段时间没有更改它了。

当我 运行 这个测试用例与整个套件时,(套件似乎总是 运行 以相同的顺序),它失败了。

失败提示Table不存在...

当我查看控制台日志时,我可以看到先前的测试执行,然后 spring 删除了数据库。然后这个测试执行并失败(数据库最终被删除)。然后 Spring 启动,JPA 在同一个 class 中为下一个测试创建数据库。如果我不知道的话,我会说 Springboot.xml 有一个错误。 看起来 Spring 未能启动此单个测试

我想也许在它之前 运行 的测试 class 有问题,但是当我 运行 这个测试在一个较小的测试块中(相同的顺序执行),包括 运行 之前和之后的测试,它 运行 没问题..

正如我所说,当我 运行 这个独立的时候,没问题 - spring 就是这样,创建数据库,执行测试,然后删除数据库...

如有任何建议,我们将不胜感激。我无法确定奇怪行为的模式或原因。

我遇到的问题似乎与@DirtiesContext 和我的控制器测试有关。我在任何对 H2 数据库进行更改的测试中使用 @DirtiesContext,因此后续测试不会受到影响。我最终删除了@DirtiesContext,并且对于每个需要数据库数据的测试,我填充它,然后使用@SQL 注释清理它(在执行阶段之前和之后)。不仅我的问题消失了,而且 651 次测试 运行 快很多(显着)快。

没有@DirtiesContext 的示例控制器测试如下所示:

@Test
@DisplayName("whitelist remote address - good")
@Sql(scripts={"/sql/remote-addresses.sql"}, executionPhase=Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts={"/sql/delete-all.sql"}, executionPhase=Sql.ExecutionPhase.AFTER_TEST_METHOD)
void whitelistAddress_good() {
    //Setup app user for test:
    AppUser testUser = TestObjects.getTestUser1();

    //Encrypt data for call:
    String dataToEncode = testUser.getAppUserId() + AppConstants.SPECIAL_DATA_DELIMETER + "1";  //row Id as inserted by the SQL...
    String dataEncoded = encryptionUtil.encrypt(dataToEncode);

    //Setup url variables:
    Map<String, String> variables = new HashMap<>();
    variables.put("encodedData", dataEncoded);

    //Setup headers:
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Type", "application/json");

    //Perform call:
    ResponseEntity<String> response = testRestTemplate.exchange(
            unirestTestUtil.getHostUrl() + AppConstants.AUTHORIZE_ADDRESS + "/{encodedData}",
            HttpMethod.PATCH,
            new HttpEntity<>(headers),
            String.class,
            variables
    );

    //Check output status:
    System.out.println("jsonResponse = " + response.getBody());
    assertEquals(HttpStatus.OK.value(),  response.getStatusCodeValue());
}