整合 extentreports、beautifulreport、allure 測試報告
extentreports 報告
網上找的各種報告整合
上效果圖,噹噹噹。。。帶錯誤截圖
pom 資訊
<!--測試報告-->
<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
com.aventstack
extentreports
3.1.5
provided
<!-- https://mvnrepository.com/artifact/com.vimalselvam/testng-extentsreport -->
com.vimalselvam
testng-extentsreport
1.3.1
com.squareup.retrofit2
retrofit
2.4.0
共用報告配置檔案
projectName.properties
url=http://172.18.2.82:8080
projectName=demo
groupName=demo
testNG 配置
<suite name="測試" parallel="false">
<!--extentreport-->
<parameter name="report.config" value="src/main/resources/report/extent-config.xml" />
<parameter name="system.info" value="com.bigfintax.report.MySystemInfo" />
<listeners>
<!--allurereport-->
<listener class-name="com.bigfintax.report.TestFailListener"/>
<!--beautifulreport-->
<listener class-name="com.bigfintax.report.TestReportListener" />
<!--extentreport-->
<listener class-name="com.bigfintax.report.MyExtentTestNgFormatter" />
</listeners>
extent-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<extentreports>
<configuration>
<timeStampFormat>yyyy-MM-dd HH:mm:ss</timeStampFormat>
<!-- report theme -->
<!-- standard, dark -->
<theme>dark</theme>
<!-- document encoding -->
<!-- defaults to UTF-8 -->
<encoding>UTF-8</encoding>
<!-- protocol for script and stylesheets -->
<!-- defaults to https -->
<protocol>https</protocol>
<!-- title of the document -->
<documentTitle>介面自動化測試報告</documentTitle>
<!-- report name - displayed at top-nav -->
<reportName>介面自動化測試報告</reportName>
<!-- report headline - displayed at top-nav, after reportHeadline -->
<reportHeadline>介面自動化測試報告</reportHeadline>
<!-- global date format override -->
<!-- defaults to yyyy-MM-dd -->
<dateFormat>yyyy-MM-dd</dateFormat>
<!-- global time format override -->
<!-- defaults to HH:mm:ss -->
<timeFormat>HH:mm:ss</timeFormat>
<!-- custom javascript -->
<scripts>
<![CDATA[
$(document).ready(function() {
});
]]>
</scripts>
<!-- custom styles -->
<styles>
<![CDATA[
]]>
</styles>
</configuration>
</extentreports>
BeautifulRrport 報告
上效果圖,噹噹噹。。。
TestReportListener 類
用於監聽@Test
/**
* @author breautiful
* @version 1.0.0
* @date 2020/1/26
*/
public class TestReportListener extends ResultListener implements IReporter {
private static TestConfig tc = new TestConfig("conf/projectName.properties");
private static Logger log = Logger.getLogger(TestReportListener.class);
// 日期格式化
private static Date date = new Date();
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd,HH點mm分ss秒");
private static String reportdate = simpleDateFormat.format(date);
private static String getReportName = tc.getValue("groupName")+"UI測試報告-" + reportdate;
// 定義html模板所在路徑
// private String templatePath = this.getClass().getResource("/").getPath() + "report/template.html";
private String templatePath = System.getProperty("user.dir") + File.separator + "src/main/resources/report/template.html";
// 定義報告生成的路徑
private String reportDirPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-output" + File.separator + "Breport";
// private String reportDirPath = System.getProperty("user.dir") + File.separator + "test-output";
// private String reportDirPath = System.getProperty("user.dir") + File.separator + "test-output" + File.separator + "beautifulReport";;
private String reportPath = reportDirPath + File.separator + getReportName + "-beautifulReport.html";
private int testsPass;
private int testsFail;
private int testsSkip;
private String beginTime;
private int totalTime;
private String project = tc.getValue("groupName")+"UI測試報告";
@Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
List<ITestResult> list = new ArrayList<ITestResult>();
for (ISuite suite : suites) {
Map<String, ISuiteResult> suiteResults = suite.getResults();
for (ISuiteResult suiteResult : suiteResults.values()) {
ITestContext testContext = suiteResult.getTestContext();
IResultMap passedTests = testContext.getPassedTests();
testsPass = testsPass + passedTests.size();
IResultMap failedTests = testContext.getFailedTests();
testsFail = testsFail + failedTests.size();
IResultMap skippedTests = testContext.getSkippedTests();
testsSkip = testsSkip + skippedTests.size();
IResultMap skippedConfig = testContext.getSkippedConfigurations();
IResultMap failedConfig = testContext.getFailedConfigurations();
list.addAll(this.listTestResult(passedTests));
list.addAll(this.listTestResult(failedTests));
list.addAll(this.listTestResult(skippedTests));
list.addAll(this.listTestResult(skippedConfig));
list.addAll(this.listTestResult(failedConfig));
}
}
this.sort(list);
this.outputResult(list);
}
private ArrayList<ITestResult> listTestResult(IResultMap resultMap) {
Set<ITestResult> results = resultMap.getAllResults();
return new ArrayList<ITestResult>(results);
}
private void sort(List<ITestResult> list) {
Collections.sort(list, new Comparator<ITestResult>() {
@Override
public int compare(ITestResult r1, ITestResult r2) {
return r1.getStartMillis() < r2.getStartMillis() ? -1 : 1;
}
});
}
public long getTime() {
return totalTime;
}
private void outputResult(List<ITestResult> list) {
try {
List<ReportInfo> listInfo = new ArrayList<ReportInfo>();
int index = 0;
for (ITestResult result : list) {
String testName = result.getTestContext().getCurrentXmlTest().getName();
if (index == 0) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
beginTime = formatter.format(new Date(result.getStartMillis()));
index++;
}
long spendTime = result.getEndMillis() - result.getStartMillis();
totalTime += spendTime;
String status = this.getStatus(result.getStatus());
List<String> log = Reporter.getOutput(result);
for (int i = 0; i < log.size(); i++) {
log.set(i, log.get(i).replaceAll("\"", "\\\\\""));
}
Throwable throwable = result.getThrowable();
if (throwable != null) {
log.add(throwable.toString().replaceAll("\"", "\\\\\""));
StackTraceElement[] st = throwable.getStackTrace();
for (StackTraceElement stackTraceElement : st) {
log.add((" " + stackTraceElement).replaceAll("\"", "\\\\\""));
}
}
ReportInfo info = new ReportInfo();
info.setName(testName);
info.setSpendTime(formatDuring(spendTime));
info.setStatus(status);
info.setClassName(result.getInstanceName());
info.setMethodName(result.getName());
info.setDescription(result.getMethod().getDescription());
info.setLog(log);
listInfo.add(info);
}
Map<String, Object> result = new HashMap<String, Object>();
log.info("!@#= 執行時間為【" + formatDuring(totalTime) + "】################");
result.put("testName", this.project);
result.put("testPass", testsPass);
result.put("testFail", testsFail);
result.put("testSkip", testsSkip);
result.put("testAll", testsPass + testsFail + testsSkip);
result.put("beginTime", beginTime);
result.put("totalTime", formatDuring(totalTime));
result.put("testResult", listInfo);
Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
String template = this.read(reportDirPath, templatePath);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(reportPath)), "UTF-8"));
template = template.replace("${resultData}", gson.toJson(result));
output.write(template);
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String getStatus(int status) {
String statusString = null;
switch (status) {
case 1:
statusString = "成功";
break;
case 2:
statusString = "失敗";
break;
case 3:
statusString = "跳過";
break;
default:
break;
}
return statusString;
}
public static class ReportInfo {
private String name;
private String className;
private String methodName;
private String description;
private String spendTime;
private String status;
private List<String> log;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getSpendTime() {
return spendTime;
}
public void setSpendTime(String spendTime) {
this.spendTime =spendTime;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List<String> getLog() {
return log;
}
public void setLog(List<String> log) {
this.log = log;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
private String read(String reportDirPath, String templatePath) {
//資料夾不存在時級聯建立目錄
File reportDir = new File(reportDirPath);
if (!reportDir.exists() && !reportDir.isDirectory()) {
reportDir.mkdirs();
}
File templateFile = new File(templatePath);
InputStream inputStream = null;
StringBuffer stringBuffer = new StringBuffer();
try {
inputStream = new FileInputStream(templateFile);
int index = 0;
byte[] b = new byte[1024];
while ((index = inputStream.read(b)) != -1) {
stringBuffer.append(new String(b, 0, index));
}
return stringBuffer.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//毫秒轉換成分鐘
public static String formatDuring(long mss) {
long days = mss / (1000 * 60 * 60 * 24);
long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
long seconds = (mss % (1000 * 60)) / 1000;
return minutes + " 分 "
+ seconds + " 秒 ";
}
}
# Allure2報告
> 上效果圖,噹噹噹。。。帶錯誤截圖
![](/uploads/photo/2021/ced091b5-a838-40e6-a81b-46ad45c94f08.png!large)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<aspectj.version>1.8.10</aspectj.version>
<allure.version>2.10.0</allure.version>
</properties>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>${allure.version}</version>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-java-commons</artifactId>
<version>2.10.0</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<excludeDefaults>true</excludeDefaults>
<plugins>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.10.0</version>
<configuration>
<reportVersion>${allure.version}</reportVersion>
</configuration>
</plugin>
</plugins>
</reporting>
> ##### allure.properties檔案
>
> ````properties
> allure.results.directory=target/allure-results
> allure.link.issue.pattern=https://example.org/issue/{}
> allure.link.tms.pattern=https://example.org/tms/{}
> allure.link.issue.pattern=http://jira.XXX.com/browse/{}
> allure.link.tms.pattern=http://testlink.XXX.com/{}
> ````
>
>
##### TestFailListener類
```java
package com.bigfintax.report;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import com.bigfintax.action.BaseAction;
import io.qameta.allure.Attachment;
/**
* allure 測試報告監聽
* @author Administrator
*
*/
public class TestFailListener extends TestListenerAdapter {
@Override
public void onTestFailure(ITestResult result) {
takePhoto();
}
@Attachment(value = "screen shot",type = "image/png")
public byte[] takePhoto(){
byte[] screenshotAs = ((TakesScreenshot)BaseAction.getDriver()).getScreenshotAs(OutputType.BYTES);
return screenshotAs;
}
}
allure 註解使用例項:
//用例編號 @TmsLink("562")
//bug編號 @Issue("4042")
/** //bug嚴重等級,優先順序,包含blocker, critical, normal, minor, trivial
* 幾個不同的等級 @Severity(SeverityLevel.TRIVIAL)
* //用例描述 @Description("測試一個流程,用作迴歸冒煙測試") /**
* 功能塊,具有相同feature或astory的用例將規整到相同模組下,執行時可用於篩選
*
* @Story("查詢場景-正向查詢功能")
*
*/
@Test(description = "驗證百度查詢功能", dataProvider = "testDemo")
@Listeners({ TestFailListener.class })
public class testcase extends BaseCase {
private Logger log = LoggerFactory.getLogger(this.getclass());
BgyAction bgyaction;
@Issue("00")
@TmsLink("00")
@Story("使用者登入")
@Description("使用者登入")
@Severity(SeverityLevel.TRIVIAL)
@Test(description = "使用者登入")
public void test00_login() {
log.info("------------------登入用例開始執行------------------");
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com");
driver.findElement(By.linkText("登入")).click();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver.findElement(By.id("TANGRAM__PSP_10__footerULoginBtn")).click();
driver.findElement(By.id("TANGRAM__PSP_10__userName")).clear();
driver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("12738749817");
driver.findElement(By.id("TANGRAM__PSP_10__password")).clear();
driver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("2222222222");
driver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
//因為有驗證碼,我們以出現驗證碼為準,做為斷言
if(driver.findElement(By.id("TANGRAM__PSP_10__error")).isDisplayed()) {
System.out.println("登入成功");
}else {
Assert.fail("斷言失敗");
}
}
log.info("------------------登入用例執行成功------------------");
}
相關文章
- Allure測試報告測試報告
- allure生成測試報告 0 NAN%測試報告NaN
- Jmeter——結合Allure展示測試報告JMeter測試報告
- pytest(11)-Allure生成測試報告(一)測試報告
- Jenkins上實現Python + Jenkins + Allure Report 介面自動化測試持續整合,並生成allure-report測試報告JenkinsPython測試報告
- allure 報告整合方案請教
- allure 測試報告怎麼嵌入到測試平臺?測試報告
- Allure測試報告完整學習筆記測試報告筆記
- Jenkins 整合 allure 報告無資料Jenkins
- Jenkins+allure整合報告構建Jenkins
- Unittest單元測試框架——BeautifulReport測試報告和Yagmail自動傳送郵件框架測試報告AI
- 如何利用Allure報告提升你的測試效率?
- Allure 測試報告:allure.title 如何去掉後方的引數化顯示測試報告
- allure測試報告不出來,json類檔案不生成測試報告JSON
- Jenkins+Allure測試報告+飛書機器人傳送通知Jenkins測試報告機器人
- 升職加薪利器:Python+Pytest框架在Jenkins上生成Allure測試報告Python框架Jenkins測試報告
- jenkins+pytest+allure 介面測試生成報告只顯示第一次的測試結果Jenkins
- pytest+allure 生成測試報告,如果保留同一個測試用例的多次執行的日誌資訊。測試報告
- Jumper 測試報告測試報告
- 雲測試報告測試報告
- 測試計劃和測試報告測試報告
- phpunit的報告結果用allure展示PHP
- 滲透測試報告測試報告
- 測試總結報告
- allure報告自定義logo圖片和文字Go
- pytest_BDD + allure 自動化測試框架框架
- pytest-testreport測試報告測試報告
- CNAS軟體測試報告測試報告
- 雲服務測試報告測試報告
- 軟體測試--缺陷報告
- 走進Java介面測試之測試報告ExtentReportJava測試報告
- Pytest-Allure報告的Logo的完美定製Go
- allure生成的報告開啟後顯示loading
- 軟體安全測試報告怎麼編寫?安全測試報告價格貴嗎?測試報告
- SpringBoot整合測試Spring Boot
- 如何編寫功能測試報告測試報告
- 效能測試報告編寫技巧測試報告
- 高顏值測試報告- XTestRunner測試報告