Подтвердить что ты не робот

Получить тестовое имя на TestNG

Можно ли получить текущее тестовое имя, например, в JUnit (используя getName() или правила)?

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

P.S. Я не хочу использовать какой-то самоналоженный инструмент, основанный на трассировке стека.

4b9b3361

Ответ 1

Согласно документации TestNG по адресу: http://testng.org/doc/documentation-main.html вы можете реализовать слушателей, которые могли бы помочь вам в решении вашей проблемы.

Посмотрите раздел 5.16 Слушатели TestNG и, в частности, IInvokedMethodListener (javadoc: http://testng.org/javadocs/org/testng/IInvokedMethodListener.html). Вы можете подключиться к beforeInvocation, чтобы захватить имя метода, удержать его где-нибудь и затем использовать его в своем тесте. Разумеется, вы можете просто использовать данные непосредственно в своей реализации.

Ответ 2

Я нашел лучшее решение с аннотацией @BeforeMethod:

import java.lang.reflect.Method;

public class Test
{ 

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

    ...
}

(на основе решения из этого потока)

Ответ 3

Когда вы используете TestNG, вы можете использовать аннотацию @BeforeTest

Попробуйте установить тест name в тестовом теге testng.xml:

<test name="Check name test" >

и используйте этот метод:

@BeforeTest
public void startTest(final ITestContext testContext) {
    System.out.println(testContext.getName()); // it prints "Check name test"
}

Ответ 4

Объявите параметр ITestContext в вашем методе и возьмите с собой любую необходимую информацию.

Ответ 5

Вам нужно быть осторожным, если удерживать значения, переданные в такие слушатели, как IInvokedMethodListener, поскольку наивная реализация (в том числе в существующих ответах) не будет потокобезопасной. Поскольку TestNG может одновременно запускать тесты, можно увидеть сохраненное значение от другого тестового слушателя. Здесь пример с двумя тестами testA() и testB():

  • beforeInvocation(testA) хранит testA
  • beforeInvocation(testB) хранит testB перезапись testA
  • testA() извлекает testB (!!)
  • testB() извлекает testB

Приведенный ниже класс TestMethodCapture правильно обрабатывает это состояние гонки, связывая слушателя и его тест с помощью ThreadLocal, гарантируя, что одновременно запущенные тесты не перезаписывают друг друга.

Более того, он не ограничивается просто получением имени теста, он содержит ссылку на ITestNGMethod и ITestResult экземпляры, связанные с текущим тестом, поэтому вы также можете проверить метод class, тестовые группы, и 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 name. This class is thread-safe.
 *
 * <p>Register this class as a
 * <a href="#" onclick="location.href='http://testng.org/doc/documentation-main.html#testng-listeners'; return false;">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 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;
}