java 如何仅使用 TestWatcher 来判断 JUnit 何时完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9942825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to tell when JUnit finishes by just using a TestWatcher?
提问by Reid Mac
I need to:
我需要:
- watch the tests
- gather information
- build a report from the tests
- 观看测试
- 收集信息
- 从测试中生成报告
The tests will be started via TeamCity. I create a TestWatcher object to listen for test results, and this TestWatcher is included in each JUnit class that contains tests. I had a listener which would listen to when the entire suite is completed, but I had to add that programmatically. Since I am now using TeamCity to run the tests and generate results, I believe I have lost that capability. I have been asked to also produce a PDF report with the TeamCity results. All I need to know is when the tests are finished so I can know when to start building my report. Is there anyway to accomplish this by just using a TestWatcher?
测试将通过 TeamCity 开始。我创建了一个 TestWatcher 对象来监听测试结果,这个 TestWatcher 包含在每个包含测试的 JUnit 类中。我有一个监听器可以在整个套件完成时监听,但我必须以编程方式添加它。由于我现在使用 TeamCity 来运行测试并生成结果,我相信我已经失去了这种能力。我还被要求制作一份包含 TeamCity 结果的 PDF 报告。我只需要知道测试何时完成,这样我就可以知道何时开始构建我的报告。有没有办法只使用 TestWatcher 来实现这一点?
Below is what my TestWatcher looks like at the moment. BaseTestResult is just a class that contains results of the tests, and organizes them in order to print them out easier. I am also using Selenium, and the driver variable is of type WebDriver:
下面是我的 TestWatcher 目前的样子。BaseTestResult 只是一个包含测试结果的类,并组织它们以便更容易地打印出来。我也在使用 Selenium,并且驱动程序变量的类型是 WebDriver:
@Rule
public TestWatcher watchman = new TestWatcher() {
private BaseTestResult currentTest;
private long startTime;
private long endTime;
@Override
protected void starting(Description d) {
startTime = System.currentTimeMillis();
currentTest = new BaseTestResult(d);
currentTest.setBrowser(type);
if (d.getAnnotation(TestDescription.class) != null) {
currentTest.setDescription(d.getAnnotation(
TestDescription.class).description());
}
currentTest.setSuite(d.getTestClass().getName());
}
@Override
protected void succeeded(Description d) {
currentTest.setSucceeded(true);
}
@Override
protected void failed(Throwable e, Description d) {
currentTest.setThrowable(e);
}
@Override
protected void finished(Description d) {
endTime = System.currentTimeMillis();
currentTest.setRuntime(endTime - startTime);
String fileName = d.getMethodName() + type + ".png";
File srcFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
String filePath = "./screens/" + fileName;
try {
FileUtils.copyFile(srcFile, new File(filePath));
currentTest.setScreenshotPath(filePath);
} catch (IOException e) {
log.severe(e.toString());
}
if (currentTest.getSucceeded()) {
BaseListener.getSuiteResult().addPassed(currentTest);
} else {
BaseListener.getSuiteResult().addFailed(currentTest);
}
// Quit, the web driver
if (driver != null) {
driver.quit();
}
}
};
回答by Petr Jane?ek
You can do this:
你可以这样做:
@ClassRule // the magic is done here
public static TestRule classWatchman = new TestWatcher() {
@Override
protected void starting(Description desc) {
System.out.println(desc.testCount()); // insert actual logic here
}
};
This watches whole class instead of every test. That means that it gives you the number of tests in a suite on the start of the suite. Then, every time you call BaseListener.getSuiteResult().addPassed(currentTest);
or BaseListener.getSuiteResult().addFailed(currentTest);
you can check whether you have already added the number of tests in a suite (meaning the suite is done).
这会监视整个班级而不是每次测试。这意味着它会在套件开始时为您提供套件中的测试数量。然后,每次调用BaseListener.getSuiteResult().addPassed(currentTest);
或者BaseListener.getSuiteResult().addFailed(currentTest);
可以检查是否已经添加了套件中的测试数量(意味着套件已完成)。
Or, even better,
或者,更好的是,
@ClassRule
public static TestRule classWatchman = new TestWatcher() {
@Override
protected void finished(Description desc) {
System.out.println("Suite completed!"); // insert actual logic here
}
};
If you have multiple classes containing tests, you can create a single AllMyTests class containing all of those! This AllMyTests class can be then run by JUnit. In this case, @ClassRule will behave as a @SuiteRule (which doesn't exist).
如果您有多个包含测试的类,您可以创建一个包含所有这些的 AllMyTests 类!这个 AllMyTests 类然后可以由 JUnit 运行。在这种情况下,@ClassRule 将表现为@SuiteRule(不存在)。
@RunWith(Suite.class)
@Suite.SuiteClasses({ First.class, Second.class, Third.class })
public class AllMyTests {
// nothing to do
}
回答by Satish
This worked for me
这对我有用
@ClassRule
public Static TestWatcher watchman= new TestWatcher() {
@Override
protected void failed(Throwable e, Description description) {
logger.info(description.getMethodName()+"Failed!"+" "+e.getMessage());
}
@Override
protected void succeeded(Description description) {
logger.info(description.getMethodName()+" " + "success!");
}
@Override
protected void finished(Description desc) {
logger.info("Suite completed!");
}
};