在TestNG上检索测试名称
我可以像在JUnit中一样检索当前运行的测试名称(使用getName()或规则 )吗?
@Test public void fooBar(){ System.out.println(magic()); //should print "fooBar" }
PS我不想使用一些基于堆栈跟踪的自编工具。
根据以下网站上的TestNG文档: http : //testng.org/doc/documentation-main.html,您可以实现可能能够帮助您解决问题的侦听器。
请参阅5.16 TestNG Listeners部分,特别是IInvokedMethodListener(javadoc: http ://testng.org/javadocs/org/testng/IInvokedMethodListener.html)。 您可以挂钩到beforeInvocation以获取方法名称,在某处保留它,然后在测试中使用它。 当然,您可以在监听器实现中立即使用详细信息。
我用@BeforeMethod注释找到了更好的解决方案:
import java.lang.reflect.Method; public class Test { @BeforeMethod public void handleTestMethodName(Method method) { String testName = method.getName(); ... } ... }
(基于此线程的解决方案)
使用TestNG时,可以使用@BeforeTest
注释
尝试在testng.xml文件测试标记中设置测试name
:
并使用此metod:
@BeforeTest public void startTest(final ITestContext testContext) { System.out.println(testContext.getName()); // it prints "Check name test" }
在方法中的参数中声明一个ITestContext
,并从中获取所需的任何信息。
在保持传递给IInvokedMethodListener
侦听器的值时需要小心,因为天真的实现(包括现有答案中的那些)将不是线程安全的。 由于TestNG可以同时运行测试,因此可以从不同的测试监听器中查看存储的值。 这是一个包含两个测试的示例: testA()
和testB()
:
-
beforeInvocation(testA)
存储testA
-
beforeInvocation(testB)
存储testB
覆盖testA
-
testA()
检索testB
(!!) -
testB()
检索testB
下面的TestMethodCapture
类通过ThreadLocal
关联监听器及其测试来正确处理此竞争条件,确保并发运行的测试不会相互覆盖。
更好的是,它不仅限于检索测试的名称,它还包含对与当前测试关联的ITestNGMethod
和ITestResult
实例的引用,因此您还可以检查方法的类 , 测试组和参数 。
您可以像这样使用它:
@Listeners(TestMethodCapture.class) public class TestMethodCaptureTest { @Test public void fooBar() { // will print "fooBar" System.out.println(TestMethodCapture.getTestMethod().getMethodName()); } }
这是class级本身:
/** * Captures the currently executing test method so it can be accessed by the test, * eg to retrieve the test method's name. This class is thread-safe. * * Register this class as a * TestNG * listener, then access the method and result from test code with the static * {@link #getTestMethod} and {@link #getTestResult} methods. * *
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 currentMethods = new ThreadLocal<>(); private static ThreadLocal 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 checkNotNull(T o, String msg, Object param) { if (o == null) { throw new NullPointerException(String.format(msg, param)); } return o; }