我们一直在使用testng
和java
来执行代码的集成测试。我们为测试执行实现了 侦听器 ,如下所示: -
public class TestExecutionListener implements IInvokedMethodListener {
@Override
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
System.out.println("Testing : " + iInvokedMethod.getTestMethod().getMethodName());
}
@Override
public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
System.out.println("Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName());
}
}
我们的 testng.xml 定义为: -
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="TestSuite" verbose="1" parallel="classes" thread-count="10">
<listeners>
<listener class-name="core.TestExecutionListener"/>
</listeners>
<test name="IntegrationTests">
<classes>
<class name="test.SomeTest1"/>
<class name="test.SomeTest2"/>
<class name="test.SomeTest3"/>
<class name="test.SomeTest4"/>
... There are more than 20 classes
</classes>
</test>
</suite>
当我们执行测试时,我们得到的输出如下:
Testing : SomeTest1Method1 Testing : SomeTest2Method2 Testing : SomeTest4Method5 Successfully Tested : SomeTest2Method2 Successfully Tested : SomeTest4Method5
虽然我们期望输出的是: -
Testing : SomeTest1Method1 Successfully Tested : SomeTest1Method1 Testing : SomeTest2Method2 Successfully Tested : SomeTest2Method2 Testing : SomeTest4Method5 Successfully Tested : SomeTest4Method5
由于xml中的parallel="classes"
属性而猜测这一点,因为将其更改为false
可提供所需的输出。但很明显,与并行执行相比,更改后的执行会消耗更多时间。
有没有办法并行运行这些测试,但仍能依次获得此输出?
答案 0 :(得分:3)
当你启用parallel时,你会注意到日志中的beforeInvocation
和afterInvocation
之间会有一段时间,并且时间差异因测试而异,因此交错输出。
如果您想要的是彼此相邻的开始和结束消息,那么您基本上是在抛出时间因素,因此只需将beforeInvocation
消息添加到afterInvocation
方法,如下所示:
public class TestExecutionListener implements IInvokedMethodListener {
@Override
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
}
@Override
public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
System.out.println("Testing : " + iInvokedMethod.getTestMethod().getMethodName());
System.out.println("Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName());
}
}
IMO这是根据您的规范执行此操作的唯一方法。但是,如果在测试期间必须收集其他信息,那么您可以在TestExecutionListener
中缓冲一些日志,例如:
public class TestExecutionListener implements IInvokedMethodListener {
private Map<Integer, Deque<String>> logsMap = new HashMap<Integer, Deque<String>>();
public void log(IInvokedMethod iInvokedMethod, String log) {
if(!logsMap.containsKey(iInvokedMethod.getId())) {
logsMap.put(iInvokedMethod.getId(), new ArrayDeque<String>());
}
logsMap.get(iInvokedMethod.getId()).add(log);
}
@Override
public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
log(iInvokedMethod, "Testing : " + iInvokedMethod.getTestMethod().getMethodName());
}
@Override
public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) {
log(iInvokedMethod, "Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName());
Deque<String> logs = logsMap.get(iInvokedMethod.getId());
while(!logs.isEmpty()) {
System.out.println(logs.poll());
}
}
}
答案 1 :(得分:0)
首先,我建议您使用log4j或类似的记录工具,这是优雅的,模块化的和提供了很多灵活的选择。这也奠定了设计和发展的道路。以多种方式处理日志记录机制。
如果您有业务需求,需要单独跟踪每个线程的日志,则应考虑将此日志流式传输到不同的文件。 Log4j类工具确实支持写入多个文件的要求。你可以只进行谷歌搜索,你将获得很多信息。