Вы должны быть осторожны при проведении на значения, переданных в слушатель, как IInvokedMethodListener
как наивная реализация (в том числе и в существующих ответах) не будет потокобезопасным. Так как TestNG может одновременно запускать тесты, можно увидеть сохраненное значение от слушателя другого теста. Вот пример с двумя тестами, testA()
и testB()
:
beforeInvocation(testA)
магазинов testA
beforeInvocation(testB)
магазины testB
перезапись testA
testA()
получает testB
(!!)
testB()
извлекает testB
Класс TestMethodCapture
правильно управляет этим состоянием гонки, связывая слушателя и его тест с помощью ThreadLocal
, гарантируя, что одновременно выполняемые тесты не перезаписывают друг друга.
Еще лучше, если это не ограничивается только получением названия теста, она содержит ссылку на обоих ITestNGMethod
и ITestResult
случаев, связанных с текущим тестом, так что вы можете также проверить метод class, test groups и 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 (почему нет ??) вы можете добавить a checkNotNUll()
метод, подобный этому, чтобы сделать эту информацию:
private static <T> T checkNotNull(T o, String msg, Object param) {
if (o == null) {
throw new NullPointerException(String.format(msg, param));
}
return o;
}
Этот ответ очень старый. Ответ Дмитрия - самый простой, требующий наименьших усилий. – gorbysbm