在 TestNG 上检索测试名称
Posted
技术标签:
【中文标题】在 TestNG 上检索测试名称【英文标题】:Retrieve test name on TestNG 【发布时间】:2012-01-25 16:00:31 【问题描述】:我能否像在 JUnit 中一样检索当前正在运行的测试名称(使用 getName() 或 rules)?
@Test
public void fooBar()
System.out.println(magic()); //should print "fooBar"
附:我不想使用一些基于堆栈跟踪的自写工具。
【问题讨论】:
【参考方案1】:根据 TestNG 文档:http://testng.org/doc/documentation-main.html 您可以实现可能能够帮助您解决问题的侦听器。
查看第 5.16 节 TestNG 侦听器,特别是 IInvokedMethodListener(javadoc:http://testng.org/javadocs/org/testng/IInvokedMethodListener.html)。您可以挂钩 beforeInvocation 以获取方法名称,在某处保留它,然后在测试中使用它。当然,您可以直接在侦听器实现中使用这些细节。
【讨论】:
这个答案很老了。德米特里的回答是最直接的,需要最少的努力。【参考方案2】:在您的方法中声明一个ITestContext
in 参数并从中获取您需要的任何信息。
【讨论】:
其实我在这个接口里面找不到context/suite/currentXmlTest name 不包含这个信息。 您的问题更像是 Java 问题而不是 TestNG 问题,并且由于您不想使用我知道的唯一方法(走堆栈跟踪),所以我不确定还有什么好说的...【参考方案3】:我用@BeforeMethod 注释找到了更好的解决方案:
import java.lang.reflect.Method;
public class Test
@BeforeMethod
public void handleTestMethodName(Method method)
String testName = method.getName();
...
...
(基于解决方案from this thread)
【讨论】:
【参考方案4】:使用TestNG时可以使用@BeforeTest
注解
尝试在 testng.xml 文件的 test 标签中设置 test name
:
<test name="Check name test" >
并使用此方法:
@BeforeTest
public void startTest(final ITestContext testContext)
System.out.println(testContext.getName()); // it prints "Check name test"
【讨论】:
【参考方案5】:在保留传递给像 IInvokedMethodListener
这样的侦听器的值时需要小心,因为幼稚的实现(包括现有答案中的那些)不会是线程安全的。由于 TestNG 可以同时运行测试,因此可以从不同测试的侦听器中查看存储的值。这是一个包含两个测试的示例,testA()
和 testB()
:
beforeInvocation(testA)
店铺testA
beforeInvocation(testB)
存储 testB
覆盖 testA
testA()
检索 testB
(!!)
testB()
检索 testB
下面的TestMethodCapture
类通过ThreadLocal
关联侦听器及其测试来正确处理这种竞争条件,确保同时运行的测试不会相互覆盖。
更好的是,它不仅限于检索测试的名称,它还包含与当前测试关联的ITestNGMethod
和ITestResult
实例的引用,因此您还可以检查方法的class、@987654325 @ 和 parameters。
你可以这样使用它:
@Listeners(TestMethodCapture.class)
public class TestMethodCaptureTest
@Test
public void fooBar()
// will print "fooBar"
System.out.println(TestMethodCapture.getTestMethod().getMethodName());
这是课程本身:
/**
* Captures the currently executing test method so it can be accessed by the test,
* e.g. to retrieve the test method's name. This class is thread-safe.
*
* <p>Register this class as a
* <a href="http://testng.org/doc/documentation-main.html#testng-listeners">TestNG
* listener</a>, then access the method and result from test code with the static
* @link #getTestMethod and @link #getTestResult methods.
*
* <p>Annotating a test class with @code @Listeners(TestMethodCapture.class) is the
* suggested way to enable capturing if your test's correctness will depend on this
* listener being enabled.
*/
public class TestMethodCapture implements IInvokedMethodListener
private static ThreadLocal<ITestNGMethod> currentMethods = new ThreadLocal<>();
private static ThreadLocal<ITestResult> currentResults = new ThreadLocal<>();
@Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult)
currentMethods.set(method.getTestMethod());
currentResults.set(testResult);
@Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult)
currentMethods.remove();
currentResults.remove();
public static ITestNGMethod getTestMethod()
return checkNotNull(currentMethods.get(),
"Did you forget to register the %s listener?", TestMethodCapture.class.getName());
/**
* Parameters passed from a data provider are accessible in the test result.
*/
public static ITestResult getTestResult()
return checkNotNull(currentResults.get(),
"Did you forget to register the %s listener?", TestMethodCapture.class.getName());
如果你不使用Guava(为什么不呢??)你可以像这样添加checkNotNUll()
方法来编译:
private static <T> T checkNotNull(T o, String msg, Object param)
if (o == null)
throw new NullPointerException(String.format(msg, param));
return o;
【讨论】:
您能解释一下返回的 checkNotNull 方法吗?我们应该定义方法吗?显示此方法未定义的错误。 @nivasan89 抱歉,我错过了您的评论。checkNotNull()
来自 Guava。我强烈建议在任何 Java 项目中使用这个库,但是这个方法本质上是对 if (foo == null) throw NullPointerException();
的一个很好的包装,所以你可以用类似的条件替换这些调用。以上是关于在 TestNG 上检索测试名称的主要内容,如果未能解决你的问题,请参考以下文章