列出将在testng中运行的测试

时间:2014-09-25 21:26:42

标签: testng

有没有办法让testng进行测试的dryrun并输出将在没有实际运行它们的情况下运行的测试的package.name.parameters?我有一个使用IHookable的部分解决方案,它无需调用IHookCallBack即可记录测试信息。这种方法的缺点是所有@Before Class/Suite/Test/Method都被调用。我们利用那些非常强大的功能并在其中添加了大量耗时的功能,我希望跳过这些功能。

3 个答案:

答案 0 :(得分:2)

TestNG在6.14版中添加了此选项(请参见here)。
要激活它,请使用JVM参数:

-Dtestng.mode.dryrun=true

答案 1 :(得分:1)

我最终实现了IMethodInterceptor仍然会调用被测系统的构造函数,以及@BeforeSuite@BeforeTest。如果SUT使用@Factory创建自身或其他类的多个实例,则该类应实现一个名为String classParameters的属性,以区别于其他类。另外,由于未调用@BeforeClass,因此依赖于调用@DataProvider的任何@BeforeClass都无法正常工作。

它并不是一个完美的解决方案,但足以满足我的需求。希望这有助于其他人。

/* DryRunListener.groovy */
import org.testng.IMethodInstance
import org.testng.IMethodInterceptor
import org.testng.ITestContext
import org.testng.annotations.DataProvider
import org.testng.annotations.Test

/*
 * This interceptor builds up a list of tests that would run without actually running them
 * The @BeforeMethod and @BeforeClass methods are NOT run, but the @BeforeSuite, @BeforeTest and constructors still run.
 * If data providers rely on the @BeforeClass methods getting called, they won't work
 */
class DryRunListener implements IMethodInterceptor {
    def tests = []

    @Override
    List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        for (method in methods) {
            // Get class name plus any parameters given by factories
            def className = getClassName(method)

            // Handling for data providers. If the method uses one, go invoke it
            def params = getParametersForMethod(method)

            tests = params.collect { "${canonicalName}.$method.method.methodName(${it.join ", "})" }
        }

        tests.each { println it } // or save it or whatever...
        return [] // tells testng - Don't run any methods!
    }

    /*
     * When using factories, there's no way to distinguish instances the factory has created.
     * TestNG has a mechanism whereby you inherit from ITest, and implement a getTestName, which is typically
     * set during a @BeforeMethod call, and is used by reporters. This requires @BeforeMethod actually be called,
     * which we don't want to do from this interceptor. Instead, we ask the testclass to implement a property for
     * returning a serialized string called classParameters, which we will append to the canonicalName of the class
     */
    String getClassName(IMethodInstance method) {
        def realClass = method.method.realClass
        def canonicalName = realClass.canonicalName
        if (realClass.metaClass.hasProperty(method.instance, "classParameters")) {
            canonicalName += "($method.instance.classParameters)"
        }
        canonicalName
    }

    /*
     * The interceptor receives the list of methods before they have been exploded for
     */
    Object[][] getParametersForMethod(IMethodInstance method) {
        def testAnnotation = method.method.constructorOrMethod.method.getAnnotation(Test.class)
        Class dataProviderClass = testAnnotation.dataProviderClass()
        if (dataProviderClass == null || dataProviderClass == Object.class) {
            dataProviderClass = method.method.realClass
        }
        String dataProviderName = testAnnotation.dataProvider()
        def dataProviderMethod = dataProviderClass.methods.find { it.getAnnotation(DataProvider.class)?.name() == dataProviderName }
        return dataProviderMethod?.invoke(method.instance) ?: [[]]
    }
}

答案 2 :(得分:0)

1)Java Reflection是你最好的朋友。您可以使用反射并获取所有信息。 2)其他可能的解决方案是使用 Xml 类(XmlTest ...)将testng.xml转换为programmitacal等效项。你会发现很多API可以帮助你实现这一目标。 如果这有帮助,请告诉我。