【问题标题】:Retrieve test name on TestNG在 TestNG 上检索测试名称
【发布时间】:2012-01-25 16:00:31
【问题描述】:

我能否像在 JUnit 中一样检索当前正在运行的测试名称(使用 getName()rules)?

@Test
public void fooBar(){
     System.out.println(magic()); //should print "fooBar"
}

附:我不想使用一些基于堆栈跟踪的自写工具。

【问题讨论】:

    标签: java testng


    【解决方案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()

        1. beforeInvocation(testA)店铺testA
        2. beforeInvocation(testB) 存储 testB 覆盖 testA
        3. testA() 检索 testB (!!)
        4. 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(); 的一个很好的包装,所以你可以用类似的条件替换这些调用。
        猜你喜欢
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多