在 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 关联侦听器及其测试来正确处理这种竞争条件,确保同时运行的测试不会相互覆盖。

更好的是,它不仅限于检索测试的名称,它还包含与当前测试关联的ITestNGMethodITestResult 实例的引用,因此您还可以检查方法的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 上检索测试名称的主要内容,如果未能解决你的问题,请参考以下文章

testng.xml 执行多个测试用例

TestNG 报告中的自定义测试方法名称

如何获取在 testng 拆卸方法中运行的测试方法的名称?

testng+selnium+eclipse的测试框架运用

在 testNG ITestListener 中获取测试方法的注释

使用java+TestNG进行接口回归测试