Java 在TestNG上检索测试名称

Java 在TestNG上检索测试名称,java,testng,Java,Testng,我是否可以像在JUnit中一样检索当前正在运行的测试名称(使用或) 另外,我不想使用一些基于堆栈跟踪的自编工具。根据TestNG文档: 您可以实现侦听器,这些侦听器可能会帮助您解决问题 请看第5.16节TestNG侦听器,特别是IInvokedMethodListener(javadoc:)。您可以钩住beforeInvocation来获取方法名,将其保留在某个位置,然后在测试中使用它。当然,您可以在侦听器实现中立即使用详细信息。在方法中的参数中声明一个ITestContext,并从中获取所需的

我是否可以像在JUnit中一样检索当前正在运行的测试名称(使用或)


另外,我不想使用一些基于堆栈跟踪的自编工具。

根据TestNG文档: 您可以实现侦听器,这些侦听器可能会帮助您解决问题


请看第5.16节TestNG侦听器,特别是IInvokedMethodListener(javadoc:)。您可以钩住beforeInvocation来获取方法名,将其保留在某个位置,然后在测试中使用它。当然,您可以在侦听器实现中立即使用详细信息。

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

我找到了使用@beforethod注释的更好解决方案:

import java.lang.reflect.Method;

public class Test
{ 

    @BeforeMethod
    public void handleTestMethodName(Method method)
    {
        String testName = method.getName(); 
        ...
    }

    ...
}

(基于解决方案)

使用TestNG时,可以使用
@BeforeTest
注释

尝试在testng.xml文件test标记中设置test
name

<test name="Check name test" >

在保留传递到侦听器(如
IInvokedMethodListener
)中的值时,需要小心,因为一个简单的实现(包括现有答案中的实现)不会是线程安全的。由于TestNG可以并发运行测试,因此可以从不同测试的侦听器中查看存储的值。下面是一个包含两个测试的示例,
testA()
testB()

  • 调用前(testA)
    存储
    testA
  • 调用前(testB)
    存储
    testB
    覆盖
    testA
  • testA()
    检索
    testB
    (!!)
  • testB()
    检索
    testB
  • 下面的
    TestMethodCapture
    类通过将侦听器与其测试通过关联,确保并发运行的测试不会相互覆盖,从而正确处理此竞争条件

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

    您可以这样使用它:

    @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());
      }
    }
    

    实际上,我在这个接口中找不到它。context/suite/currentXmlTest name不包含此信息。您的问题更像是Java问题,而不是TestNG问题,因为您不想使用我知道的唯一方法(遍历堆栈跟踪),我不知道还有什么要说的…你能解释一下返回的checkNotNull方法吗?我们应该定义方法吗?它显示未定义此方法的错误。@nivasan89抱歉,我错过了您的评论。是从哪里来的。我强烈建议在任何Java项目中使用这个库,但是这个方法本质上是一个很好的包装器,可以包装
    if(foo==null)throw NullPointerException()@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());
      }
    }
    
    private static <T> T checkNotNull(T o, String msg, Object param) {
      if (o == null) {
        throw new NullPointerException(String.format(msg, param));
      }
      return o;
    }