想知道为什么即使我没有将它附加到 TestClass 而不是 xml 文件,我的 customListener 也会被调用..?
因此,我制作了一个实现 ITestListener、IClassListener 的自定义记录器侦听器。
现在我将此侦听器附加到我的测试类之一,而第二个测试类没有附加侦听器。
现在我已将两个测试类放入 1 个套件 xml 文件中。
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite A">
<test name="FirstSuiteFirstClassTest" >
<classes>
<class name="ITClassTestA"/>
</classes>
</test>
<test name="FirstSuiteSecondClassTest" >
<classes>
<class name="ITClassTestB"/>
</classes>
</test>
</suite>
@Listeners({LoggerListener.class})
public class ITClassTestA extends BaseTest {
@Test
public void test1InClassTestA() throws InterruptedException {
logger.info("Started test 1 in ClassTest A: " + TimeUtils.nowUTC());
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
logTheName("SDK");
logger.info("Ended test 1 in ClassTest A: " + TimeUtils.nowUTC());
}
@Test
public void test2InClassTestA() throws InterruptedException {
logger.info("Started test 2 in ClassTest A: " + TimeUtils.nowUTC());
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
logger.info("Ended test 2 in ClassTest A: " + TimeUtils.nowUTC());
}
}
public class ITClassTestB extends BaseTest {
@Test
public void test1InClassTestB() throws InterruptedException {
logger.info("Started test 1 in ClassTest B at: " + TimeUtils.nowUTC());
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
logTheName("testNG");
logger.info("Ended test 1 In ClassTest B at: " + TimeUtils.nowUTC());
}
@Test
public void test2InClassTestB() throws InterruptedException {
logger.info("Started test 2 In ClassTest B at: " + TimeUtils.nowUTC());
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
logger.info("Ended test 2 In ClassTest B at: " + TimeUtils.nowUTC());
}
}
public abstract class BaseTest {
protected Logger logger;
@BeforeMethod
public void createLog() {
}
@BeforeClass
public void beforeAll() {
if (logger == null) {
logger = LogManager.getLogger(this.getClass().getSimpleName());
}
}
@AfterClass
public void afterAll() {
logger.info("Bye dude");
}
protected void logTheName(String name) {
logger.info("The name is {}", name);
}
}
public class LoggerListener implements ITestListener, IClassListener {
private final Map<String, List<TestResultStatus>> testResultsStatusPerClass = new ConcurrentHashMap<>();
private enum TestResultStatus {
SUCCESSFUL, FAILED, TIMED_OUT, SKIPPED;
}
@Override
public void onBeforeClass(ITestClass testClass) {
Class<?> testRealClass = testClass.getRealClass();
String testClassName = testRealClass.getSimpleName();
initLogFile(testClassName);
}
@Override
public void onAfterClass(ITestClass testClass) {
List<TestResultStatus> resultStatuses = testResultsStatusPerClass.get(testClass.getRealClass().getSimpleName());
Map<TestResultStatus, Long> summary = resultStatuses
.stream()
`Here I get NPE, because resultStatuses doesn't find the test class name in the map`
我没有附上 `LoggerListener` 的其余代码..
但我试图理解的主要事情是,当我没有将记录器监听器附加到 TestClassB 时,onBeforeClass 和 onAfterClass 是如何被触发的。
我看到有运行时调用的testNg的
invokeBeforeClassMethods
,还有listener.onBeforeClass()...
无法得出结论。
TestNG 提供了以下 3 种将侦听器连接到其中的方法。
@Listeners
注释<listeners>
。但是无论使用什么机制连接侦听器,TestNG 中的侦听器本质上始终是全局的。
因此,这意味着将为所有类执行侦听器。
如果您希望侦听器有选择地仅适用于定义它的那些类,那么您需要确保在测试代码中添加该过滤逻辑。
例如,您可以将侦听器更改为如下所示:
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
import org.testng.annotations.Listeners;
public class SampleLoggingListener implements IInvokedMethodListener {
@Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
boolean isPresent = testResult.getTestClass().getRealClass()
.isAnnotationPresent(Listeners.class);
if (isPresent) {
System.err.println("Executing method " + method.getTestMethod().getQualifiedName());
}
}
}