#maven #selenium-webdriver #testng #extentreports #selenium-extent-report
#maven #selenium-webdriver #testng #extentreports #selenium-extent-report
Вопрос:
Я использую testng 6.9.10, extentreports 3.1.5. Используя плагин maven surefire и используя forkcount и reuse forks , тесты выполняются параллельно. (т. Е. открываются два экземпляра браузера Chrome с двумя тестовыми классами, запущенными параллельно, поскольку я установил forkcount -> 2 и reuseforks-> true)
mvn test -Dgroups=group1
(есть два тестовых класса, принадлежащих group1). Проблема в том, что отчет о степени показывает только результат последнего запуска.
Я включил только класс прослушивателя в pom.xml (нигде больше, не в @beforeclass или @afterclass как часть класса BaseTest)
<property>
<name>listener</name>
<value>util.listener.TestExtentListener</value>
</property>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<forkCount>2</forkCount>
<reuseForks>true</reuseForks>
Любое решение, пожалуйста?
public class ExtentManager {
private static ExtentReports extent;
private static String reportFileName = "Test-Automaton-Report" ".html";
private static String fileSeperator = System.getProperty("file.separator");
private static String reportFilepath = System.getProperty("user.dir") fileSeperator "TestReport";
private static String reportFileLocation = reportFilepath fileSeperator reportFileName;
public static ExtentReports getInstance() {
if (extent == null)
createInstance();
return extent;
}
//Create an extent report instance
public static ExtentReports createInstance() {
String fileName = getReportPath(reportFilepath);
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(fileName);
htmlReporter.config().setTestViewChartLocation(ChartLocation.BOTTOM);
htmlReporter.config().setChartVisibilityOnOpen(true);
htmlReporter.config().setTheme(Theme.STANDARD);
htmlReporter.config().setDocumentTitle(reportFileName);
htmlReporter.config().setEncoding("utf-8");
htmlReporter.config().setReportName(reportFileName);
htmlReporter.config().setTimeStampFormat("EEEE, MMMM dd, yyyy, hh:mm a '('zzz')'");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
//Set environment details
extent.setSystemInfo("OS", "Mac");
extent.setSystemInfo("AUT", "QA");
return extent;
}
//Create the report path
private static String getReportPath (String path) {
File testDirectory = new File(path);
if (!testDirectory.exists()) {
if (testDirectory.mkdir()) {
System.out.println("Directory: " path " is created!" );
return reportFileLocation;
} else {
System.out.println("Failed to create directory: " path);
return System.getProperty("user.dir");
}
} else {
System.out.println("Directory already exists: " path);
}
return reportFileLocation;
}
}
public class ExtentTestManager {
static Map<Integer, ExtentTest> extentTestMap = new HashMap<Integer, ExtentTest>();
static ExtentReports extent = ExtentManager.getInstance();
public static synchronized ExtentTest getTest() {
return (ExtentTest) extentTestMap.get((int) (long) (Thread.currentThread().getId()));
}
public static synchronized void endTest() {
extent.flush();
}
public static synchronized ExtentTest startTest(String testName) {
ExtentTest test = extent.createTest(testName);
extentTestMap.put((int) (long) (Thread.currentThread().getId()), test);
return test;
}
}
public class TestExtentListener implements ITestListener {
ExtentTest test;
private static ThreadLocal<ExtentTest> extentTestThreadLocal = new ThreadLocal<ExtentTest>();
public void onStart(ITestContext context) {
System.out.println("*** Test Suite " context.getName() " started ***");
}
public void onFinish(ITestContext context) {
System.out.println(("*** Test Suite " context.getName() " ending ***"));
ExtentTestManager.endTest();
ExtentManager.getInstance().flush();
}
public void onTestStart(ITestResult result) {
System.out.println(("*** Running test method " result.getMethod().getMethodName() "..."));
test = ExtentTestManager.startTest(result.getMethod().getMethodName());
extentTestThreadLocal.set(test);
}
public void onTestSuccess(ITestResult result) {
System.out.println("*** Executed " result.getMethod().getMethodName() " test successfully...");
extentTestThreadLocal.get().log(Status.PASS, "Test passed");
}
public void onTestFailure(ITestResult result) {
System.out.println("*** Test execution " result.getMethod().getMethodName() " failed...");
extentTestThreadLocal.get().log(Status.FAIL, "Test Failed");
}
public void onTestSkipped(ITestResult result) {
System.out.println("*** Test " result.getMethod().getMethodName() " skipped...");
extentTestThreadLocal.get().log(Status.SKIP, "Test Skipped");
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
System.out.println("*** Test failed but within percentage % " result.getMethod().getMethodName());
}
}
Ответ №1:
возможно, вы не используете локальный класс thread в Java, чтобы сделать отчет о степени потокобезопасным. В противном случае объекты будут переопределены, а отчет о степени показывает только результаты активных тестов.
Вы можете сделать что-то вроде этого:
ExtentReports extent = ExtentReportGenerator.ExtentReport();
ExtentTest test;;
private static ThreadLocal<ExtentTest> extent_test = new ThreadLocal<ExtentTest>();
Для получения более подробной информации вы можете обратиться к этому блогу.
https://www.automationinja.com/post/thread-safe-extent-report-in-selenium
Ответ №2:
If you use xml file to your testclasses all report will appear in extent report
This is my XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TC_WorldAirFares Automation Test Suite">
<listeners>
<listener class-name="ExtentReports.ExtentReporterNG" />
</listeners>
<suite name="Suite" parallel="instances" thread-count="2">
<test name="TC Automation Test Suite">
<classes>
<class name="Footerlinks" />
<class name="HeaderLinks" />
<class name="BookYourFlightsNow" />
</classes>
</test>
</suite>
keep class for extentreports
here extent report class (XML file listen your extentreport class and generate reports for you test classes
package ExtentReports;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;
import org.testng.*;
import org.testng.xml.XmlSuite;
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class ExtentReporterNG implements IReporter {
private ExtentReports extent;
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
String outputDirectory) {
extent = new ExtentReports(outputDirectory File.separator
"Extent.html", true);
for (ISuite suite : suites) {
Map<String, ISuiteResult> result = suite.getResults();
for (ISuiteResult r : result.values()) {
ITestContext context = r.getTestContext();
buildTestNodes(context.getPassedTests(), LogStatus.PASS);
buildTestNodes(context.getFailedTests(), LogStatus.FAIL);
buildTestNodes(context.getSkippedTests(), LogStatus.SKIP);
}
}
extent.flush();
extent.close();
}
private void buildTestNodes(IResultMap tests, LogStatus status) {
ExtentTest test;
if (tests.size() > 0) {
for (ITestResult result : tests.getAllResults()) {
test = extent.startTest(result.getMethod().getMethodName());
test.setStartedTime(getTime(result.getStartMillis()));
test.setEndedTime(getTime(result.getEndMillis()));
for (String group : result.getMethod().getGroups())
test.assignCategory(group);
if (result.getThrowable() != null) {
test.log(status, result.getThrowable());
} else {
test.log(status, "Test " status.toString().toLowerCase()
"ed");
}
extent.endTest(test);
}
}
}
private Date getTime(long millis) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millis);
return calendar.getTime();
}
}
Комментарии:
1. Я не вижу из вашего xml, что он выполняется параллельно. Я сталкиваюсь с проблемой только тогда, когда он работает параллельно. Для одного потока он создает правильный отчет. Для параллельного запуска он показывает только результат последнего запуска . В качестве примера class1 имеет 2 метода, помеченных как Test. Class2, имеющий 3 метода, помеченных как Test. В этом случае скажем, что class2 завершен последним. Таким образом, он показывает только 3 метода class2. Он переопределяет результат из class1.
2. Когда я использую приведенный выше xml, он не выполняется параллельно, но, однако, если я запускаю плагин surefire с подсчетом вилок, хотя он выполняется параллельно, но он всегда дает мне один результат. Внутри junitreports в целевом каталоге (внутри папки surefire reports) указано правильное количество xml-файлов. (один XML на класс). Однако testng-results.xml всегда выдает результат одного класса (класс заканчивается последним).