为什么当我没有将自定义侦听器附加到 TestClass 时,而不是通过注释或套件 xml 文件来调用它? (测试NG)

问题描述 投票:0回答:1

想知道为什么即使我没有将它附加到 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()... 无法得出结论。

java maven testing testng
1个回答
0
投票

TestNG 提供了以下 3 种将侦听器连接到其中的方法。

  • 通过
    @Listeners
    注释
  • 通过套件文件中的 xml 标签
    <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());
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.