所以我有一个套房,就像这样:
@RunWith(Suite.class)
@Suite.SuiteClasses({TestClass1.class, TestClass2.class, TestClass3.class})
public class TestSuite {
static List<ExtentTest> extentTestList = new ArrayList<>();
@ClassRule
public static ExtentWatcher extentWatcher = new ExtentWatcher() {
@Override
protected void starting(Description description) {
extentTestList.addAll(extentWatcher.getTests());
}
@Override
protected void finished(Description description) {
extentWatcher.flushReports(extentTestList);
}
};
}
上面的代码有效,但问题是它会导致我的Watcher报告套件的结果,而不是单独的测试。此外,如果测试失败,套件仍会报告为已通过。我的看守是这样的:
public class ExtentWatcher extends TestWatcher {
// A little set up to give the report a date in the file name
private DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
private Date date = new Date();
private String fileDate = dateFormat.format(date);
private String reportName = "./Test_Report_" + fileDate + ".html";
public ExtentReports extent;
ArrayList<ExtentTest> testList = new ArrayList<>();
public ExtentWatcher() {
extent = createReport();
}
// If test passed, watcher will record this with Extent Reports
@Override
protected void succeeded(Description description) {
ExtentTest test = extent.startTest(description.getDisplayName());
test.log(LogStatus.PASS, "Test Run Successful");
testList.add(test);
}
// Likewise in case of failure
@Override
protected void failed(Throwable e, Description description) {
ExtentTest test = extent.startTest(description.getDisplayName());
test.log(LogStatus.FAIL, "Test Failure: " + e.toString());
testList.add(test);
}
/**
* These methods do the legwork - this file is based off of an example I found @ www.kieftsoft.nl/?p=81
* Eventually we can add some screenshot logic here, but just a clean test report and version info will do
*/
private ExtentReports createReport() {
// Create the report - Extent just needs a little config
ExtentReports extent = new ExtentReports(reportName, false);
extent.config().reportName("Test Report: " + fileDate);
return extent;
}
public void flushReports(List<ExtentTest> testList) {
// This ends the test and then sends (flushes) everything to the html document
for(ExtentTest test : testList) extent.endTest(test);
extent.flush();
}
public List<ExtentTest> getTests() {
return testList;
}
}
对于单个测试,此代码可以很好地注释为@Rule(每个测试都有一个单独的报告,不可取),但是如上所述,这不适用于套件级别而且我是真的不知道如何让它发挥作用。我以为我可以收集所有测试的列表,并在套件中结束测试并刷新它们,这将允许ExtentReport给我一份所有测试的报告。但是,我无法专门获得单独的测试结果 - 我将返回一个测试,其中displayName()=套件名称。
如何跟踪各个测试,然后在完成所有测试后对其进行刷新,让ExtentWatcher在测试的基础上处理测试的通过/失败,而不仅仅是套件的一次?
答案 0 :(得分:1)
我使用RunListener实现,它将结果记录在一个文件中。首先,我有一个测试运行器类,可以为每个测试套件调用:
@Override
public void testFailure(Failure failure) throws Exception {
classLogger.log(Level.CONFIG, failure.getMessage());
classLogger.log(Level.CONFIG, failure.getTestHeader());
classLogger.log(Level.CONFIG, failure.getTrace());
classLogger.log(Level.CONFIG, failure.getDescription().getDisplayName());
if (failure.getException() != null) {
classLogger.log(Level.CONFIG, failure.getException().getMessage());
}
super.testFailure(failure);
Description description = failure.getDescription();
Test test = processTestResult(TestStatus.FAIL, description);
if (test == null) {
classLogger.log(Level.SEVERE, "TEST IS NULL:" + description.getDisplayName());
return;
}
classLogger.log(Level.CONFIG, failure.getMessage()+ " " + description.getDisplayName());
test.setFailureMessage(description.getDisplayName());
test.setFailureException(failure.getException());
LogRecord record = new LogRecord(Level.CONFIG, failure.getMessage());
record.setParameters(new Object[] { test, failure });
testFailuresLogger.log(record);
}
TestRun类是一个自定义类,它只计算具有以下条件的测试数:启动,传递,失败,忽略。
TestRunListener实现了org.junit.runner.notification.RunListener,并根据回调(例如testFailure(),testFinished()等)跟踪有关测试状态的信息。
has_many
答案 1 :(得分:0)
TestSuite类中指定的上面的代码有效,但问题是它导致了我的Watcher 报告套件的结果,而不是单独的测试。
ClassRule
在类级别执行,并且不能为每个单独的测试执行它们。因此,您的观察者不会报告个别测试。
由于您有兴趣列出每个单独测试级别的事件,因此您可以使用org.junit.runner.notification.RunListener
(而不是Watcher)。为了避免在每个测试类中指定监听器,您可以实现自己的Suite测试运行器,它将自动注册自定义RunListener。
例如:
public class SuiteRunner extends Suite {
public SuiteRunner(Class<?> klass) throws InitializationError {
super(klass, new JUnit4Builder());
}
@Override
public void run(RunNotifier notifier) {
notifier.addFirstListener(new RunListener() {
@Override
public void testRunStarted(Description description) throws Exception {
// add to watcher
}
@Override
public void testFailure(Failure failure) throws Exception {
// add to watcher
}
});
super.run(notifier);
}
}
在Test Suite类中指定此跑步者
@RunWith(SuiteRunner.class)
@Suite.SuiteClasses({ MyTest.class , MyTest2.class })
public class TestSuite {
@ClassRule
public static ExtentWatcher watcher = new ExtentWatcher();
}
希望它有所帮助。