我可以像在JUnit中一样检索当前运行的测试名称(使用getName()或规则)吗?
@Test
public void fooBar(){
System.out.println(magic()); //should print "fooBar"
}
Run Code Online (Sandbox Code Playgroud)
PS我不想使用一些基于堆栈跟踪的自编工具.
Dmi*_*try 49
我用@BeforeMethod注释找到了更好的解决方案:
import java.lang.reflect.Method;
public class Test
{
@BeforeMethod
public void handleTestMethodName(Method method)
{
String testName = method.getName();
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
(基于此线程的解决方案)
Tom*_*ski 12
使用TestNG时,您可以使用@BeforeTest注释
尝试name在testng.xml文件测试标记中设置test :
<test name="Check name test" >
Run Code Online (Sandbox Code Playgroud)
并使用此metod:
@BeforeTest
public void startTest(final ITestContext testContext) {
System.out.println(testContext.getName()); // it prints "Check name test"
}
Run Code Online (Sandbox Code Playgroud)
ITestContext在方法中声明一个in参数,并从中获取所需的任何信息.
小智 6
根据以下网站上的TestNG文档:http://testng.org/doc/documentation-main.html, 您可以实现可能能够帮助您解决问题的侦听器.
请参阅第5.16节TestNG Listeners,特别是IInvokedMethodListener(javadoc:http://testng.org/javadocs/org/testng/IInvokedMethodListener.html ).您可以挂钩到beforeInvocation以获取方法名称,在某处保留它,然后在测试中使用它.当然,您可以在监听器实现中立即使用详细信息.
在保留传递给侦听器的值时,您需要小心,IInvokedMethodListener因为天真的实现(包括现有答案中的值)将不是线程安全的。由于TestNG可以同时运行测试,因此可以从其他测试的侦听器查看存储的值。这是带有两个测试的示例,testA()并且testB():
beforeInvocation(testA) 商店 testAbeforeInvocation(testB)商店testB覆盖testAtestA()检索testB(!!)testB() 检索 testBTestMethodCapture下面的类通过通过关联侦听器及其测试来正确处理此竞争条件ThreadLocal,以确保同时运行的测试不会相互覆盖。
更好的是,它不仅限于检索测试的名称,还包含与当前测试关联的ITestNGMethod和ITestResult实例的引用,因此您还可以检查方法的类,测试组和参数。
您可以这样使用它:
@Listeners(TestMethodCapture.class)
public class TestMethodCaptureTest {
@Test
public void fooBar() {
// will print "fooBar"
System.out.println(TestMethodCapture.getTestMethod().getMethodName());
}
}
Run Code Online (Sandbox Code Playgroud)
这是课程本身:
/**
* 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());
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不使用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;
}
Run Code Online (Sandbox Code Playgroud)