Java 一个测试观察者报告JUnit套件中单个测试的结果

Java 一个测试观察者报告JUnit套件中单个测试的结果,java,junit,annotations,webdriver,automated-tests,Java,Junit,Annotations,Webdriver,Automated Tests,所以我有一个套房,像这样: @RunWith(Suite.class) @Suite.SuiteClasses({TestClass1.class, TestClass2.class, TestClass3.class}) public class TestSuite { static List<ExtentTest> extentTestList = new ArrayList<>(); @ClassRule public static Ex

所以我有一个套房,像这样:

@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);
        }
    };
}
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;
    }
}
@RunWith(Suite.class)
@SuiteClasses({TestClass1.class,TestClass2.class,TestClass3.class})
公共类测试套件{
静态列表扩展列表=新的ArrayList();
@阶级规则
公共静态ExtentWatcher ExtentWatcher=新ExtentWatcher(){
@凌驾
受保护的无效启动(说明){
addAll(extentWatcher.getTests());
}
@凌驾
已完成受保护的作废(说明){
extentWatcher.flushReports(extentTestList);
}
};
}
上面的代码可以工作,但问题是它导致我的观察者报告套件的结果,而不是单个测试的结果。此外,如果测试失败,套件仍然报告通过。我的观察者是这样的:

@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);
        }
    };
}
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;
    }
}
公共类ExtentWatcher扩展TestWatcher{
//在文件名中为报告指定日期的小设置
private DateFormat DateFormat=新的SimpleDateFormat(“dd-MM-yyyy”);
私有日期=新日期();
私有字符串fileDate=dateFormat.format(日期);
私有字符串reportName=“./Test_Report_”+fileDate+“.html”;
公共延伸范围;
ArrayList testList=新的ArrayList();
公共扩展记录器(){
extent=createReport();
}
//如果测试通过,观察者将用扩展报告记录此情况
@凌驾
受保护的无效已成功(说明){
ExtentTest test=extent.startTest(description.getDisplayName());
test.log(LogStatus.PASS,“测试运行成功”);
testList.add(test);
}
//同样,如果发生故障
@凌驾
受保护无效失败(可丢弃e,说明){
ExtentTest test=extent.startTest(description.getDisplayName());
test.log(LogStatus.FAIL,“测试失败:+e.toString());
testList.add(test);
}
/**
*这些方法做了大量的工作-这个文件基于我在www.kiefsoft.nl/?p=81上找到的一个例子
*最终,我们可以在这里添加一些屏幕截图逻辑,但只需一个干净的测试报告和版本信息即可
*/
私有ExtentReports createReport(){
//创建报告-扩展只需要一点配置
ExtentReports区段=新的ExtentReports(reportName,false);
extent.config().reportName(“测试报告:”+fileDate);
返回范围;
}
公共无效flushReports(列表testList){
//这将结束测试,然后将所有内容发送(刷新)到html文档
对于(扩展测试:testList)extent.endTest(测试);
expndure.flush();
}
公共列表getTests(){
返回测试列表;
}
}
这段代码可以很好地注释为单个测试的@Rule(每个测试都有一个单独的报告,这是不可取的),但是如上所述,这在套件级别上不起作用,我真的不知道如何使它工作。我想我可以收集所有测试的列表,在套件中,结束测试并刷新它们,这将允许ExtentReport向我提供所有测试的报告。但是,我无法具体获取单个测试结果-我将返回一个测试,其中displayName()=套件名称


我如何跟踪单个测试,然后在所有测试完成后刷新它们,并让ExtentWatcher逐个测试处理通过/失败,而不是只对套件执行一次?

我使用RunListener实现,它将结果记录在一个文件中。首先,我有一个test runner类,可以为每个测试套件调用该类:

public Result run(String suite) {
    Class<?> suiteClass = null;
    try {
      suiteClass = Class.forName(suite);
    } catch (ClassNotFoundException ex) {
      return null;
    }
    JUnitCore core = new JUnitCore();
    this.testRun = new TestRun(testLogging, suite);
    core.addListener(new TestRunListener(testLogging, testRun));
    Result result = core.run(suiteClass);
    return(result);
}
上面的代码是有效的,但问题是它导致了我的Watcher 报告套件的结果,而不是单个测试的结果

TestSuite类中指定的
ClassRule
在类级别执行,不能针对每个单独的测试执行。因此,您的观察者不会针对单个测试进行报告

因为您对列出每个测试级别的事件感兴趣,所以可以使用
org.junit.runner.notification.RunListener
(而不是Watcher)。为了避免在每个测试类中指定监听器,您可以实现自己的套件测试运行程序,它将自动注册自定义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);
    }
}

希望有帮助。

在成功和失败中添加flushReports后,它是否有效?与问题无关-为什么不更新到最新版本?否,如果刷新成功或失败,我将获得每个测试的报告。我目前使用的是最新版本。@SeeYaLater Automator:我也遇到了同样的问题。您是否有可能找到它?@user1466466您是否尝试在
ExtentReports
中覆盖
开始
完成