JUnit5 - 如何在 AfterTestExecutionCallback 中获取测试结果

JUnit5 - How to get test result in AfterTestExecutionCallback

我写 JUnit5 扩展。但是我找不到如何获得测试结果的方法。

扩展看起来像这样:

import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.TestExtensionContext;

public class TestResultExtension implements AfterTestExecutionCallback {
    @Override
    public void afterTestExecution(TestExtensionContext context) throws Exception {
        //How to get test result? SUCCESS/FAILED
    }
}

任何提示如何获得测试结果?

我只有这个解决方案:

String testResult = context.getTestException().isPresent() ? "FAILED" : "OK";

看来效果不错。但我不确定它是否在所有情况下都能正常工作。

JUnit 中的失败通过异常传播。有几个异常,表示各种类型的错误。

因此 TestExtensionContext#getTestException() indicates an error. The method can't manipulate actual test results, so depending on your use case you might want to implement TestExecutionExceptionHandler 中的异常允许您吞下异常,从而改变测试是否成功。

正如其他答案所指出的,, so an AfterTestExecutionCallback can be used 。请注意,这很容易出错,因为扩展 运行 稍后可能仍无法通过测试。

另一种方法是 register a custom TestExecutionListener. Both of these approaches are a little roundabout, though. There is an issue that tracks a specific extension point for reacting to test results, which would likely be the most straight-forward answer to your question. If you can provide a specific use case, it would be great if you could head over to #542 并留下描述它的评论。

这对我有用:

public class RunnerExtension implements AfterTestExecutionCallback {

    @Override
    public void afterTestExecution(ExtensionContext context) throws Exception {
        Boolean testResult = context.getExecutionException().isPresent();
        System.out.println(testResult); //false - SUCCESS, true - FAILED
    }
}

@ExtendWith(RunnerExtension.class)
public abstract class Tests {

}

您可以使用 org.junit.platform.launcher.listeners

中的 SummaryGeneratingListener

它包含 MutableTestExecutionSummary 字段,它实现了 TestExecutionSummary 接口,通过这种方式您可以获取有关容器、测试、时间、失败等信息。

您可以创建自定义侦听器,例如:

  1. 创建扩展 SummaryGeneratingListener
  2. 的 class
public class ResultAnalyzer extends SummaryGeneratingListener {
    @Override
    public void testPlanExecutionFinished(TestPlan testPlan) {
        //This method is invoked after all tests in all containers is finished
        super.testPlanExecutionFinished(testPlan);
        analyzeResult();
    }

    private void analyzeResult() {
        var summary = getSummary();
        var failures = summary.getFailures();
        //Do something
    }
}
  1. 通过创建文件注册监听器

src\main\resources\META-INF\services\org.junit.platform.launcher.TestExecutionListener

并在其中指定您的实现

path.to.class.ResultAnalyzer

  1. 启用自动检测扩展,设置参数

-Djunit.jupiter.extensions.autodetection.enabled=true

就是这样!

文档

https://junit.org/junit5/docs/5.0.0/api/org/junit/platform/launcher/listeners/SummaryGeneratingListener.html

https://junit.org/junit5/docs/5.0.0/api/org/junit/platform/launcher/listeners/TestExecutionSummary.html

https://junit.org/junit5/docs/current/user-guide/#extensions-registration-automatic

你快到了。

要实现测试执行回调并获取用于记录(或生成报告)的测试结果,您可以执行以下操作:

import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

public class TestResultExtension implements AfterTestExecutionCallback
{
    @Override
    public void afterTestExecution(ExtensionContext context) throws Exception
    {
        // check the context for an exception 
        Boolean passed = context.getExecutionException().isEmpty();
        
        // if there isn't, the test passed
        String result = passed ? "PASSED" : "FAILED";

        // now that you have the result, you can do whatever you want 
        System.out.println("Test Result: " + context.getDisplayName() + " " + result);
    }
}

然后您只需使用 @ExtendWith() 注释为您的测试用例添加 TestResultExtension:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.junit.jupiter.api.Assertions.assertTrue;

@ExtendWith(TestResultExtension.class)
public class SanityTest
{
    @Test
    public void testSanity()
    {
        assertTrue(true);
    }

    @Test
    public void testInsanity()
    {
        assertTrue(false);
    }
}

最好扩展包含扩展的基础测试

import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(TestResultExtension.class)
public class BaseTest
{}

然后你不需要在每个测试中都包含注释:

public class SanityTest extends BaseTest
{ //... }