Я работаю над платформой автоматизации и использую Extent Report в качестве инструмента отчетности. Я регистрирую журналы Android и действия пользователей с помощью журнала Slf4j.
Я хотел запускать тесты параллельно. Я хочу регистрировать журналы Android и мои действия пользователя в отношении моего теста. А потому, что это не потокобезопасно. Итак, я получаю журналы одного теста в другом. Вот мой код для последовательных тестов:
Класс прослушивателя
Код: Выделить всё
ExtentTest test;
ExtentReports extent=ExtentReporterNG.getReporterObject();
AppiumDriver driver;
@Override
public void onTestStart(ITestResult result) {
test=extent.createTest(result.getMethod().getMethodName());
ExtentReportsAppender.setExtentTest(test);
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
ExtentReportsAppender extentAppender = new ExtentReportsAppender();
extentAppender.setName("ExtentReportsAppender");
extentAppender.start(); // Start the appender
rootLogger.addAppender(extentAppender);
try {
driver=(AppiumDriver) result.getTestClass().getRealClass().getField("driver")
.get(result.getInstance());
} catch (Exception e) {
e.printStackTrace();
}
try {
((CanRecordScreen) driver).startRecordingScreen();
}
catch(Exception e) {
}
}
@Override
public void onTestSuccess(ITestResult result) {
test.log(Status.PASS, "Test Passed");
((CanRecordScreen) driver).stopRecordingScreen();
cleanupLogger();
}
@Override
public void onTestFailure(ITestResult result) {
test.fail(result.getThrowable());
try {
stopRecording(result.getMethod().getMethodName());
}
catch(Exception e) {
}
cleanupLogger();
}
@Override
public void onTestSkipped(ITestResult result) {
test.skip(result.getThrowable());
}
@Override
public void onFinish(ITestContext context) {
extent.flush();
}
private void cleanupLogger() {
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
ExtentReportsAppender extentAppender = (ExtentReportsAppender) rootLogger.getAppender("ExtentReportsAppender");
if (extentAppender != null) {
rootLogger.detachAppender(extentAppender); // Detach the appender
extentAppender.stop(); // Stop the appender
}
}
public void stopRecording(String methodName) throws IOException {
String media = ((CanRecordScreen) driver).stopRecordingScreen();
String dirPath = System.getProperty("user.dir")+File.separator+"videos";
File videoDir = new File(dirPath);
FileOutputStream stream = null;
try {
stream = new FileOutputStream(videoDir + File.separator +methodName+".mp4");
stream.write(Base64.decodeBase64(media));
stream.close();
} catch (Exception e) {
} finally {
if(stream != null) {
stream.close();
}
}
}
Код: Выделить всё
public class ExtentReportsAppender extends AppenderBase{
private static ExtentTest test;
public static void setExtentTest(ExtentTest testInstance) {
test = testInstance;
}
@Override
protected void append(ILoggingEvent event) {
if (test != null) {
switch (event.getLevel().levelInt) {
case Level.INFO_INT:
test.log(Status.INFO, event.getFormattedMessage());
break;
case Level.WARN_INT:
test.log(Status.WARNING, event.getFormattedMessage());
break;
}
}
}
I created a thread Local variable for Extent Test and my Appium Driver that i get from reflection. Благодаря этому отчет об экстентах теста и видеозапись стали потокобезопасными, а журналы - нет.
Класс прослушивателя
< предварительно>
Код: Выделить всё
public class Listeners extends AppiumUtils implements ITestListener,IConfigurationListener{
ExtentReports extent=ExtentReporterNG.getReporterObject();
AppiumDriver driver;
private ThreadLocal driverThreadLocal = new ThreadLocal();
private ThreadLocal testThreadLocal = new ThreadLocal();
private ThreadLocal appenderThreadLocal = new ThreadLocal();
@Override
public void onTestStart(ITestResult result) {
ExtentTest test=extent.createTest(result.getMethod().getMethodName());
testThreadLocal.set(test);
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
ExtentReportsAppender extentAppender = new ExtentReportsAppender(testThreadLocal.get());
appenderThreadLocal.set(extentAppender);
extentAppender.setName("ExtentReportsAppender");
extentAppender.start(); // Start the appender
rootLogger.addAppender(extentAppender);
try {
driver = (AppiumDriver) result.getTestClass().getRealClass().getField("driver")
.get(result.getInstance());
driverThreadLocal.set(driver);
} catch (Exception e) {
e.printStackTrace();
}
try {
((CanRecordScreen) driver).startRecordingScreen();
}
catch(Exception e) {
}
}
@Override
public void onTestSuccess(ITestResult result) {
testThreadLocal.get().log(Status.PASS, "Test Passed");
try {
driver=driverThreadLocal.get();
} catch (Exception e) {
e.printStackTrace();
}
((CanRecordScreen) driver).stopRecordingScreen();
cleanupLogger();
}
@Override
public void onTestFailure(ITestResult result) {
testThreadLocal.get().fail(result.getThrowable());
try {
driver=driverThreadLocal.get();
} catch (Exception e) {
e.printStackTrace();
}
try {
stopRecording(result.getMethod().getMethodName());
}
catch(Exception e) {
}
/*try {
driver=(AppiumDriver) result.getTestClass().getRealClass().getField("driver")
.get(result.getInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
test.addScreenCaptureFromBase64String(getScreenshotAsBase64(driver),"Screenshot");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
cleanupLogger();
}
@Override
public void onTestSkipped(ITestResult result) {
testThreadLocal.get().fail(result.getThrowable());
}
@Override
public void onFinish(ITestContext context) {
extent.flush();
}
private void cleanupLogger() {
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
// ExtentReportsAppender extentAppender = (ExtentReportsAppender) rootLogger.getAppender("ExtentReportsAppender");
ExtentReportsAppender extentAppender=appenderThreadLocal.get();
if (extentAppender != null) {
rootLogger.detachAppender(extentAppender); // Detach the appender
extentAppender.stop(); // Остановка приложения
}
public void stopRecording(String MethodName) бросает IOException {
AppiumDriver driver = driverThreadLocal.get();
String media = ((CanRecordScreen) driver).stopRecordingScreen();
String dirPath = System.getProperty("user.dir")+File.separator+"videos";
Файл videoDir = новый файл(dirPath) );
поток FileOutputStream = null;
try {
поток = новый FileOutputStream(videoDir + File.separator +methodName+».mp4");
stream.write (Base64.decodeBase64(media));
stream.close();
} catch (Exception e) {
} наконец {
if (поток != null) {
stream.close();
Код: Выделить всё
public class ExtentReportsAppender extends AppenderBase{
private ExtentTest test;
public ExtentReportsAppender(ExtentTest testInstance) {
test = testInstance;
}
@Override
protected void append(ILoggingEvent event) {
if (test != null) {
switch (event.getLevel().levelInt) {
case Level.INFO_INT:
test.log(Status.INFO, event.getFormattedMessage());
break;
case Level.WARN_INT:
test.log(Status.WARNING, event.getFormattedMessage());
break;
}
}
}
- By setting the thread safe testInstance instead of a static test will print relevant test logs.
- By Setting the AppenderThreadLocal on Test Start and by Getting it in Clean up logger will clean that test's logs
Источник: https://stackoverflow.com/questions/781 ... hread-safe