如何在TestNG的tearDown方法中获取运行的测试方法的名称?

36
基本上,我有一个拆卸方法,我想记录到控制台中运行了哪个测试。我该如何获取这个字符串?
我可以获取类名,但我想要实际执行的方法。
public class TestSomething {

    @AfterMethod
    public void tearDown() {
        System.out.println("The test that just ran was: " + getTestThatJustRanMethodName());
    }

    @Test
    public void testCase() {
       assertTrue(1 == 1);
    }
}

应该在屏幕上输出:"刚才运行的测试是:testCase"

然而,我不知道getTestThatJustRanMethodName究竟应该是什么神奇的东西。

5个回答

50

在你的 @AfterMethod 中声明一个类型为 ITestResult 的参数,TestNG 将会注入它:

@AfterMethod
public void afterMethod(ITestResult result) {
  System.out.println("method name:" + result.getMethod().getMethodName());
}

谢谢,我使用“Reporter.setCurrentTestResult(result);”来将报告流更改为测试方法。 - naive

35

如果您想在测试执行之前获取方法名称,可以使用以下方法:

import java.lang.reflect.Method;

@BeforeMethod
public void nameBefore(Method method)
{
    System.out.println("Test name: " + method.getName());       
}

同样适用于@AfterMethod...这是OP所要求的 ;) - René Link
帮助了我。 ✓ - Y-B Cause
对我没用 org.testng.TestNGException: 只能将 <ITestContext, XmlTest> 中的一个注入到 @AfterClass 注释的 tearDown 中。 - JPM

8

只需声明一个java.lang.reflect.Method参数即可。

 @BeforeMethod
 public void beforeTestMethod(Method testMethod){
    System.out.println("Before Testmethod: " + testMethod.getName());       
 }

但是TestNG允许您进行更多的注入操作;)
  • 任何@Before方法或@Test方法都可以声明一个类型为ITestContext的参数。
  • 任何@AfterMethod方法都可以声明一个类型为ITestResult的参数,该参数将反映刚刚运行的测试方法的结果。
  • 任何@Before@After方法都可以声明一个类型为XmlTest的参数,其中包含当前的 tag
  • 任何@BeforeMethod(和@AfterMethod)都可以声明一个类型为java.lang.reflect.Method的参数。此参数将接收此@BeforeMethod结束后将要调用的测试方法(或在@AfterMethod运行之后)。
  • 任何@BeforeMethod都可以声明一个类型为Object[]的参数。此参数将接收即将提供给即将到来的测试方法的参数列表,这些参数可以由TestNG注入,例如java.lang.reflect.Method,也可以来自@DataProvider
  • 任何@DataProvider都可以声明一个类型为ITestContextjava.lang.reflect.Method的参数。后一个参数将接收即将被调用的测试方法。

2

除了Cedric的答案虽然不太简单,TestNG支持这种方式的另一种方法是注册监听器

@Listeners({MethodListener.class})
public class ListenerTest {

  @Test
  public void someTest() {
  }

}

听众可能会看起来像这样:

public class MethodListener implements IInvokedMethodListener {

  @Override
  public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

  }

  @Override
  public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
    System.out.println(method.getTestMethod().getMethodName());
  }
}

这个特定的侦听器会将方法名称(即someTest)打印到控制台。它将在每次执行测试后被执行。

如果您是通过编程方式生成testSuite,则可以按照以下方式添加侦听器,而不是在每个测试类上添加@Listeners({MethodListener.class})

    List<String> listeners = new ArrayList<String>();
    listeners.add(MethodListener.class.getName());
    testSuite.setListeners(listeners);

你只需要使用 testResult.getMethod().getMethodName() 即可,无需获取 IInvokedMethod。 - Bochu

1
在我的项目中,我通过JUnit的@Rule来访问这些数据。
String testName;
String className;

@Rule
public TestWatcher watcher = new TestWatcher() {
    public void starting(Description description) {
        testName = description.getMethodName();
        className = description.getClassName();
        logger.info("Starting test " + testName + " in class " + className);
    }
};

2
这个问题是关于TestNG而不是JUnit的。 - opticyclic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接