Получить название теста на TestNG - PullRequest
15 голосов
/ 22 декабря 2011

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

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

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

Ответы [ 5 ]

43 голосов
/ 30 августа 2012

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

import java.lang.reflect.Method;

public class Test
{ 

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

    ...
}

(на основе решения из этой темы )

12 голосов
/ 07 февраля 2014

Когда вы используете 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"
}
7 голосов
/ 22 декабря 2011

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

6 голосов
/ 22 декабря 2011

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

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

5 голосов
/ 05 июня 2016

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

  1. beforeInvocation(testA) хранилища testA
  2. beforeInvocation(testB) хранилища testB перезапись testA
  3. testA() извлекает testB (!!)
  4. testB() извлекает testB

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

Более того, он не ограничивается простым получением имени теста, он содержитссылка на экземпляры ITestNGMethod и ITestResult, связанные с текущим тестом, так что вы также можете проверить группы теста class , метода и параметры .

Вы можете использовать его так:

@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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...