在TestNG上检索测试名称

Sta*_*lin 17 java testng

我可以像在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)


Ced*_*ust 7

ITestContext在方法中声明一个in参数,并从中获取所需的任何信息.

  • 您的问题更像是一个 Java 问题而不是 TestNG 问题,并且由于您不想使用我知道的唯一方法(走堆栈跟踪),我不知道还能说什么... (2认同)

小智 6

根据以下网站上的TestNG文档:http://testng.org/doc/documentation-main.html, 您可以实现可能能够帮助您解决问题的侦听器.

请参阅第5.16节TestNG Listeners,特别是IInvokedMethodListener(javadoc:http://testng.org/javadocs/org/testng/IInvokedMethodListener.html ).您可以挂钩到beforeInvocation以获取方法名称,在某处保留它,然后在测试中使用它.当然,您可以在监听器实现中立即使用详细信息.

  • 这个答案很老了.德米特里的答案是最直接的,需要最少的努力. (2认同)

dim*_*414 6

在保留传递给侦听器的值时,您需要小心,IInvokedMethodListener因为天真的实现(包括现有答案中的值)将不是线程安全的。由于TestNG可以同时运行测试,因此可以从其他测试的侦听器查看存储的值。这是带有两个测试的示例,testA()并且testB()

  1. beforeInvocation(testA) 商店 testA
  2. beforeInvocation(testB)商店testB覆盖testA
  3. testA()检索testB(!!)
  4. testB() 检索 testB

TestMethodCapture下面的类通过通过关联侦听器及其测试来正确处理此竞争条件ThreadLocal,以确保同时运行的测试不会相互覆盖。

更好的是,它不仅限于检索测试的名称,还包含与当前测试关联的ITestNGMethodITestResult实例的引用,因此您还可以检查方法的测试组参数

您可以这样使用它:

@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)