testng自定义报告生成,配置钉钉机器人发送测试结果
通过jenkins集成自动化job,存在一些不足之处
- 邮件发送不容易被相关人员关注
- jenkins集成的钉钉内容不够丰富
创建钉钉工具类
按照钉钉机器人开发文档,定义一个钉钉发送消息的工具类
public class DingTalkRobot { /** * 钉钉机器人签名 */ private String secret; /** * 钉钉机器人webhook */ private String url; public DingTalkRobot(String secret, String url) { this.secret = secret; this.url = url; } /* * 方法描述 获取签名 */ private String signature(String timestamp) throws Exception { String stringToSign = timestamp + "\n" + secret; Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8"); } public String sendLinkMsg(String msg) throws Exception { String timestamp = String.valueOf(System.currentTimeMillis()); HttpClient httpclient = HttpClients.createDefault(); String postUrl = url + "×tamp=" + timestamp + "&sign=" + signature(timestamp); HttpPost httppost = new HttpPost(postUrl); httppost.addHeader("Content-Type", "application/json; charset=utf-8"); httppost.addHeader("sign", signature(timestamp)); httppost.addHeader("timestamp", timestamp); StringEntity se = new StringEntity(msg, "utf-8"); httppost.setEntity(se); String result = null; HttpResponse response = httpclient.execute(httppost); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { result = EntityUtils.toString(response.getEntity()); } return result; } }
创建监听器
创建一个监听器,继承Ireporter
,并且重写generateReport
方法
public class ReportListener implements IReporter { int totalTestCase = 0; double passRate = 0; int failNum = 0; int passNum = 0; int skipNum = 0; String projectName=""; String jobName = ""; @Override public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) { for (ISuite suite : suites) { Map<String, ISuiteResult> results = suite.getResults(); projectName += results.keySet(); for (ISuiteResult suiteResult : results.values()) { passNum += suiteResult.getTestContext().getPassedTests().getAllResults().size(); failNum += suiteResult.getTestContext().getFailedTests().getAllResults().size(); skipNum += suiteResult.getTestContext().getSkippedTests().getAllResults().size(); } } totalTestCase = passNum + failNum + skipNum; passRate = new BigDecimal((float) passNum / totalTestCase * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); String url = "钉钉webhook"; String secret = "签名密钥"; // 调用钉钉工具类的发消息方法 DingTalkRobot dingTalkRobot = new DingTalkRobot(secret, url); try { dingTalkRobot.sendLinkMsg(convertToLink()); } catch (Exception e) { e.printStackTrace(); } } /** * 组装发送的消息 */ private String convertToLink() { JSONObject sendObj = new JSONObject(); JSONObject linkObj = new JSONObject(); linkObj.put("title", projectName); linkObj.put("text", "用例数:" + totalTestCase + "通过率:" + passRate+ "\n通过:" + passNum + "\t失败:" + failNum + "\t跳过:" + skipNum ); linkObj.put("picUrl", ""); linkObj.put("messageUrl", "http://你的jenkinsIp/view/Selenium/" + "/job/" + "你的job名" + "/allure/"); sendObj.put("msgtype", "link"); sendObj.put("link", linkObj); return sendObj.toString(); } }
在testng的xml文件重加入监听
....省略 <listeners> <listener class-name="com.yxt.listener.ScreenShotPC" /> <listener class-name="org.uncommons.reportng.HTMLReporter"/> <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/> <listener class-name="com.yxt.listener.ReportListener"/> </listeners> ....省略
最终效果