Как в TestNG Listener витащить имя тестового класа, имя тестового метода и параметри xml сюта при паралельном запуске тестов ?

Задача следующая - есть listener-и и прочий код которий что то делает для однопоточного фреймворка, теперь переходим на SauceLabs:

что б запустить тести паралельно на 25-и VM -ах одновременно нужно внедрить параллелизм , - в фреймворке у меня такой косяк:

 @BeforeClass(alwaysRun = true)
 public void setupTestBase(ITestContext context) throws Exception {
 	LOG.info("TestBase before class method - setting logTestFolder");
 	System.setProperty("logTestFolder", getTestClassName()
				+ getTestParams(context));
 }

private String getTestClassName() {
		return this.getClass().getSimpleName();
}

private String getTestParams(ITestContext context) {
 	StringBuilder testNameWithParams = new StringBuilder("");
 	Map<String, String> testParams = context.getCurrentXmlTest()
 				.getAllParameters();
 	for (Entry<String, String> entry : testParams.entrySet()) {
 		testNameWithParams.append("_" + entry.getValue());
 	}
	return testNameWithParams.toString();
}

потом в Listener-e я ету системную переменную достаю и подставляю куда то там - logTestFolder . Как теперь при переходе на ThreadLocal и многопоточность шарить стейт ? Все листенери extends TestListenerAdapter.

Писался код для однопоточного запускаи свои проблеми он решает. Еще один трабл ето то что TestBase внутри /src/test/java , а listener-и, как полагаеться в /src/main/java …

P.S. Прикручен Allure Report в фреймворке, - не било ли у Вас проблем с репортом после перехода на parallel execution в surefire-plugin ? Я имею ввиду колизии в репортинге , атачментах итд ?

Шарить стейт чего? Пока не понятно, в чем именно затык. Да и зачем вам перед каждым классом вычитывать значения всех параметров? При таком подходе их можно вычитать лишь раз. Другое дело, если вам нужны параметры более низкого уровня. Но не видя вашей xml, сложно о чем-то говорить.

та ето для репорта, параметри (браузер, енвайрмент) потом в название сюта аппендятся в Аллюр репорт, дергаю перед каждим классом, так как для каждого класса свой сют)

Откажитесь от системной переменной. В Listener, который наследует TestListenerAdapter, есть метод onTestStart(ITestResult iTestResult), где вы можете вытащить имя теста
```iTestResult.getName();`

и контекст, с которого можете вытащить параметры:
```iTestResult.getTestContext();`

как получить имя теста которий будет раниться перед тестом ? Аля onTestBeforeMethod листенер … что то типо тово

Там есть метод beforeConfiguration(ITestResult tr), с которого вы тоже можете вытащить имя

beforeConfiguration перед @BeforeMethod и @BeforeClass не возвращает ничего…

А зачем вам имя теста, который будет раниться перед каким-то конкретным тестом, если не секрет?

не не, мне нужно имя тестового метода перед визовом всех его @Before методов…

@BeforeMethod на то и придумали, чтобы проводить всю подготовительную работу. Что вы собираетесь подготавливать до вызова @BeforeMethod? Сдается мне, что где-то закралась архитектурная проблема.

Но у теста на самом деле может быть N @BeforeMethod в случае наследования (у каждого чайлда свой Before).

На худой конец можно воспользоваться AspectJ библиотекой, и перехватывать вызовы всех Before.

такс, проблема решена, - переписал чуток архитектуру - теперь ето все lister-и делают.
Появился другой вопрос:
как к TestNG тесту свою анотацию запилить и как читать ее в екзекюшин тайме ?

например, если тестовий метод имеет анотацию @ABTesting значит для него нужно кое что сделать итд.
Мне нужно для потока , в котором тести с такой анотацией будут запускаться, что параметр с анотации читался и подставлялся в методи других класов, не листенеров и не контекстов testng - для однопоточности работало через System переменную …

Создаете кастомную аннотацию, ну а TestNG позволяет инжектить спец. структуру типа Method в сигнатуру @BeforeMethod, а также @DataProvider. Далее, при помощи reflection можно получить список всех аннотаций тестового метода и делать с ними все, что угодно.

@BeforeMethod
public void setUp(ITestContext context, Method method) {
}
1 лайк

Все верно. reflection сделает все что Вам нужно с Вашей аннотацией.

да я так и делал, но как ето витащить для многопоточности и потом передать в другие класи ? например в клас Page (base клас для пейдж обджектов) ?

Например у меня есть @ABTesting(optimizely = true) над тестом - значит в один из методов класса класса Page мне нужно переда значение optimizely теста поточного потока екзекюшина…

Если этот параметр относится к данным / доменной логике, то вставляйте прямо в DataProvider output. Если у него какое-то более сакральное конфигурационное значение уровня самого фреймворка, то можно сетить на уровне @BeforeMethod из, к примеру, ранер класса в ThreadLocal контейнер.

Хотя, я бы все-таки вынес эту опцию на уровень отдельного конфигурационного класса. У вас ведь наверняка есть набор потокозависимых пропертей. Вот и соберите их в единый класс, объект которого и будет помещен в ThreadLocal со статическим геттером.

да так и сделал, ThreadLocal популейтиться перед запуском а потом static get-тером подсталвяеться куда нужно, - пока что работает нормально) Всем спасибо