测试报告代码如下(其是实现了testNg的监听)
package com.cn.frame.SelfReport; import java.io.File; import java.io.IOException; import java.util.Date; import org.apache.log4j.Logger; import org.testng.ITestContext; import org.testng.ITestResult; import org.testng.TestListenerAdapter; import com.cn.frame.Utills.DateformatUtils; import com.cn.frame.Utills.FileUtils; import com.cn.frame.mailDispatch.MailDispatch; public class TestReport extends TestListenerAdapter{ public int failure=0; public int success=0; public int skip=0; static Logger log=Logger.getLogger(TestReport.class); File htmlReportDir = new File("test-output/html-report"); String reportName = DateformatUtils.getCurrentDateTime()+".html"; String reportPath = htmlReportDir+"/"+reportName; File report = new File(htmlReportDir,reportName); String smtp = "smtp.163.com"; //发送人 String username="xxx"; String password="xxxx"; String from = "xxxx"; //接收人 //String[] to = {"xxxx"}; String[] to = {"xxxx"}; //抄送人 String[] copyto = {}; String subject = "主题"; String content = "邮件内容"; MailDispatch email = new MailDispatch(smtp, username, password); @Override public void onFinish(ITestContext context) { String msg = "</tbody></table></body></html>"; FileUtils.writeFile(report, msg, "utf-8", true); // email.sendMail(from, to, copyto, subject, content, reportPath); System.out.println(success+" "+failure+" "+skip+" "); } @Override public void onStart(ITestContext arg0) { //1.判断报告输出的目录是否存在 if (!htmlReportDir.exists()) { htmlReportDir.mkdirs(); } if(report.exists()){ try { report.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } String msg = "<html>" + "<head><meta http-equiv="Content-Type" content="text/html; " + "charset=utf-8" />" + "<meta name="author" content="ec-qa:xin.wang">" + "<style type="text/css">"+ ".log { display: none;} "+ ".stack-trace { display: none;}"+ ".datatable tr:hover,.datatable tr.hilite"+ " {background-color:#99FF66;color:#0000CC; }"+ "</style>"+ "<script type="text/javascript">"+ "function flip(e) {"+ "current = e.style.display;"+ " if (current == 'block') {"+ " e.style.display = 'none';"+ "return 0;"+ " }"+ " else {"+ " e.style.display = 'block';"+ "return 1;"+ "}"+ "}"+ "function toggleBox(szDivId, elem, msg1, msg2)"+ "{"+ " var res = -1; "+ " if (document.getElementById) "+ " {"+ " res = flip(document.getElementById(szDivId));"+ " } "+ " else if (document.all) { "+ " res = flip(document.all[szDivId]);"+ " }"+ " if(elem){ "+ " if(res == 0) elem.innerHTML = msg1;"+ " else elem.innerHTML = msg2;"+ " }"+ " } "+ "function toggleAllBoxes() { "+ " if (document.getElementsByTagName) { "+ " d = document.getElementsByTagName('div'); "+ " for (i = 0; i < d.length; i++) { "+ " if (d[i].className == 'log') { "+ " flip(d[i]); "+ " } "+ " } "+ " } "+ "} "+ "</script>"+ "<script type="text/javascript">"+ " var rows=document.getElementsByTagName("tr");"+ " for (var i = 0; i < rows.length; i++) {"+ " rows[i].onmouseover = function(){"+ " this.className += 'hilite';"+ "}"+ "rows[i].onmouseout = function(){"+ "this.className = this.className.replace('hilite','');"+ " }"+ " }"+ "</script>"+ "<meta name="description" content="自动化测试用例结果列表">" + "<title>UI自动化测试报告</title>" + "</head>" + "<body STYLE="background-color:#00CCCC; text-align:center;">" + "<br>" + "<a style="font-weight:bold; text-align:center;">测试用例运行结果列表</a>" + "<br>" + "<br>" + "<table class="datatable" width="100%" height="80" border="1" align="center" style="table-layout:fixed;">" + "<thead>" + "<tr>" + "<th>测试用例名</th>" + "<th>测试用例结果</th>" + "</tr>" + "</thead>" + "<tbody style="word-wrap:break-word;font-weight:bold;">"; FileUtils.writeFile(report, msg, "UTF-8", true); } @Override public void onTestFailure(ITestResult result) { String screenShotTip =result.getMethod().getMethodName() + " failed " ; StringBuilder caseRes = new StringBuilder("<tr><td>"); caseRes.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName()); caseRes.append("</td><td><br>"); caseRes.append(screenShotTip); caseRes.append("<br><br>"); Throwable throwable = result.getThrowable(); caseRes.append("测试用例 运行失败,原因: "); caseRes.append("<font color="red">"+throwable.getMessage()+"</font>"); caseRes.append("<br><br>"); caseRes.append("<a href='#' " + "onClick='toggleBox("stack-trace22537571", this, "Click to show all stack frames", "Click to hide stack frames")'>" + "Click to show all stack frames" + "</a>"); caseRes.append("<div class='stack-trace' id='stack-trace22537571'><pre>"); StackTraceElement[] se = throwable.getStackTrace(); caseRes.append("堆栈信息:"); caseRes.append("<br>"); for (StackTraceElement e : se) { caseRes.append(e.toString().trim()); caseRes.append("<br>"); } caseRes.append("</pre></div>"); caseRes.append("</td></tr>"); String res = caseRes.toString(); FileUtils.writeFile(report, res, "utf-8", true); failure=failure+1; } @Override public void onTestSkipped(ITestResult result) { StringBuilder caseRes = new StringBuilder("<tr><td>"); caseRes.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName()); caseRes.append("</td><td>Skipped</td></tr>"); String res = caseRes.toString(); FileUtils.writeFile(report, res, "utf-8", true); skip=skip+1; } @Override public void onTestStart(ITestResult arg0) { } @Override public void onTestSuccess(ITestResult result) { StringBuilder caseRes = new StringBuilder("<tr><td>"); caseRes.append(result.getMethod().getRealClass()+"."+result.getMethod().getMethodName()); caseRes.append("</td><td>Passed</td></tr>"); String res = caseRes.toString(); FileUtils.writeFile(report, res, "utf-8", true); success=success+1; } @Override public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) { } }