Java&Selenium&TestNG&ZTestReport 自动化测试并生成HTML自动化测试报告

一、摘要

本篇博文将介绍如何借助ZTestReport和HTML模版,生成HTML测试报告的ZTestReport 源码Clone地址为 https://github.com/zhangfei19841004/ztest,其中ZTestReport.java

和其template是我们需要的关键。

二、ZTestReport.java

根据我的需要,在源码基础上进行了稍微修改,其中几个注释的地方需要注意,将其集成进自己的自动化框架时需要做相应的修改

package util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.testng.*;
import org.testng.xml.XmlSuite;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;

public class TestReport implements IReporter {
    private long currentTime = System.currentTimeMillis();
    private SimpleDateFormat formatter = new SimpleDateFormat ("yyyy年-MM月-dd日-HH时mm分ss秒");
    private Date date = new Date(currentTime);
    private String reportdate = formatter.format(date);
    // 定义生成测试报告的路径和文件名,为兼容Windows和Linux此处使用File.separator代替分隔符
    private String path = System.getProperty("user.dir")+File.separator+reportdate+".html";
    // 定义html样式模板所在路径
    private String templatePath = System.getProperty("user.dir")+File.separator+"template";

    private int testsPass = 0;

    private int testsFail = 0;

    private int testsSkip = 0;

    private String beginTime;

    private long totalTime;

    private String name = "PaaS平台自动化测试";
    /**
    public TestReport(){
        long currentTime = System.currentTimeMillis();
        SimpleDateFormat formatter = new SimpleDateFormat ("yyyy年-MM月-dd日-HH时mm分ss秒");
        Date date = new Date(currentTime);
        name = formatter.format(date);
    }

    public TestReport(String name){
        this.name = name;
        if(this.name==null){
            long currentTime = System.currentTimeMillis();
            SimpleDateFormat formatter = new SimpleDateFormat ("yyyy年-MM月-dd日-HH时mm分ss秒");
            Date date = new Date(currentTime);
            this.name = formatter.format(date);
        }
    }
    */
    @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 failedConfig = testContext.getFailedConfigurations();
                list.addAll(this.listTestResult(passedTests));
                list.addAll(this.listTestResult(failedTests));
                list.addAll(this.listTestResult(skippedTests));
                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) {
                if (r1.getStartMillis() > r2.getStartMillis()) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
    }

    private void outputResult(List<ITestResult> list) {
        try {
            List<ReportInfo> listInfo = new ArrayList<ReportInfo>();
            int index = 0;
            for (ITestResult result : list) {
                String tn = result.getTestContext().getCurrentXmlTest().getParameter("testCase");
                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(tn);
                info.setSpendTime(spendTime+"ms");
                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>();
            result.put("testName", name);
            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", totalTime+"ms");
            result.put("testResult", listInfo);
            Gson gson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
            String template = this.read(templatePath);
            BufferedWriter output = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(new File(path)),"UTF-8"));
            template = template.replaceFirst("\\$\\{resultData\\}", Matcher.quoteReplacement(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 path) {
        File file = new File(path);
        InputStream is = null;
        StringBuffer sb = new StringBuffer();
        try {
            is = new FileInputStream(file);
            int index = 0;
            byte[] b = new byte[1024];
            while ((index = is.read(b)) != -1) {
                sb.append(new String(b, 0, index));
            }
            return sb.toString();
        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

三、template

template文件是和ZTestReport.java一起使用的,他可以将TestNG的测试结果按照template的样式转换成HTML格式的报告

四、调用ZTestReport.java

方式一:在测试类添加监听

package testscript;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.*;
import org.testng.Assert;
import org.testng.annotations.*;
import util.KeyActionsUtil;
import static util.KeyActionsUtil.*;
import java.util.List;
import static appmodule.MysqlService.linkToMysqlPage;
import static util.KeyBoardUtil.pressTabKey;
import static util.LogUtil.info;
import static pageobject.resourcemanagement.MySQLService.*;
import static util.ScrollBarUtil.scrolltoBottom;
import static util.WaitElementUtil.sleep;
// @Listeners({util.TestReport.class})
public class Test_Mysql {

    static {
        DOMConfigurator.configure("log4j.xml");
    }
    @BeforeClass
    public void setUp()throws Exception {
        WebDriver driver = KeyActionsUtil.initBrowser("chrome");
        linkToMysqlPage(driver, "yangdawei", "alex005x");
        sleep(2000);
    }

    @Test(priority = 0, description = "测试创建mysql数据库服务1CPU2G")
    public void test_CreateMysqlInstance() throws Exception {
        create_New_Instance_Button(driver).click();
        info("点击创建实例按钮...");
        sleep(1000);
        info("等待3秒...");
        instance_Name_in_Create_Instance_Dialog(driver).sendKeys("automationtest");
        info("输入实例名:automationtesta");
        sleep(1000);
        info("等待3秒...");
        //页面存在相同属性的元素,取所有放到list里,用序号操作
        List<WebElement> radios = driver.findElements(By.className("el-radio-button__inner"));
        radios.get(1).click();
        sleep(1000);
        info("选择数据库版本5.7...");
        instance_Standard_in_Create_Instance_Dialog(driver).click();
        info("点击实例规格...");
        sleep(2000);
        info("等待2秒...");
        one_Core_two_GB(driver).click();
        info("选择1CPU2GB...");
        storage_Space_in_Create_Instance_Dialog(driver).clear();
        info("清空存储空间字段...");
        storage_Space_in_Create_Instance_Dialog(driver).sendKeys("1");
        info("输入1G....");
        scrolltoBottom(driver);
        sleep(2000);
        pressTabKey();
        outsideaccess_Checkbox_in_Create_Instance_Dialog(driver).click();
        info("选择外部链接...");
        password_in_Create_Instance_Dialog(driver).sendKeys("111111");
        info("输入密码111111...");
        repassword_in_Create_Instance_Dialog(driver).sendKeys("111111");
        info("确认密码111111...");
        description_in_Create_Instance_Dialog(driver).sendKeys("automationtest");
        info("描述信息输入automationtest");
        sleep(2000);
        submit_Button_in_Create_Instance_Dialog(driver).sendKeys(Keys.ENTER);
        info("确认创建...");
        sleep(2000);
        refresh_Button(driver).click();
        Assert.assertTrue(driver.getPageSource().contains("automationtest"));
        Assert.assertTrue(driver.getPageSource().contains("创建中"));
    }
    @Test(priority = 1, description = "重启mysql服务")
    public void test_RestartMysqlInstance()throws Exception {
        operation_Button(driver).click();
        info("点击列表里最后一列的...");
        sleep(2000);
        info("等待3秒...");
        operation_Restart_Button(driver).click();
        info("点击下拉菜单中的重启按钮...");
        sleep(2000);
        info("等待3秒...");
        restart_Confirm_Button(driver).click();
        info("点击确定按钮...");
        sleep(2000);
        info("等待3秒...");
        Assert.assertTrue(driver.getPageSource().contains("重启请求成功"));
        Assert.assertTrue(driver.getPageSource().contains("重启中"));
    }

    @Test(priority = 2, description = "管理mysql服务页面")
    public void test_Review_Basic_Mysql_Info()throws Exception{
        operation_Button(driver).click();
        info("点击列表里最后一列的...");
        sleep(2000);
        info("等待3秒...");
        operation_Manage_Button(driver).click();
        info("点击下拉菜单里的管理按钮...");
        sleep(2000);
        info("等待三秒");
        assertString(driver,"基本信息");
    }
    @Test(priority = 3, description = "管理mysql服务页面")
    public void test_Review_Mysql_Link()throws Exception{
        database_Link_Tab(driver).click();
        sleep(2000);
        Assert.assertTrue(driver.getPageSource().contains("210.13.50.105"));
    }

    @Test(priority = 4,description = "查看Mysql日志")
    public void test_ReviewLog()throws Exception{
        operation_Button(driver).click();
        info("点击列表里最后一列的...");
        sleep(2000);
        info("等待3秒...");
        operation_Log_Button(driver).click();
        info("点击下拉菜单中的日志按钮...");
        sleep(2000);
        info("等待3秒...");
        extend_Button_in_Log_Page(driver).click();
        info("点击展开按钮...");
        sleep(2000);
        info("等待3秒...");
        datefrom_in_Log_Page(driver).click();
        info("点击第一个日期空间,弹出下拉...");
        sleep(2000);
        info("等待3秒...");
        datefrom_by_Date_in_Log_Page(driver).clear();
        datefrom_by_Date_in_Log_Page(driver).sendKeys("2018-09-01");
        info("输入日期”2018-09-01");
        sleep(2000);
        info("等待3秒...");
        datefrom_Sure_Button_in_Log_Page(driver).click();
        info("点击确定按钮...");
        sleep(2000);
        info("等待3秒...");
        search_Button_in_Log_Page(driver).click();
        info("点击筛选按钮...");
        sleep(2000);
        info("等待3秒...");
        Assert.assertTrue(driver.getPageSource().contains("Initializing database"));

    }

    @Test(priority = 5, description = "查看Mysql服务监控")
    public void test_MonitorMysqlService()throws Exception{
        operation_Button(driver).click();
        info("点击列表里最后一列的...");
        sleep(3000);
        info("等待3秒...");
        operation_Monitor_Button(driver).click();
        info("点击下拉菜单里的监控按钮...");
        sleep(3000);
        info("等待3秒...");
    }

    @Test(priority = 6, description = "释放mysql服务")
    public void test_ReleaseMysqlService()throws Exception{
        operation_Button(driver).click();
        info("点击列表里最后一列的...");
        sleep(3000);
        info("等待3秒...");
        operation_Release_Button(driver).click();
        info("点击下拉菜单里的释放按钮...");
        sleep(3000);
        info("等待3秒...");
        release_Confirm_Button(driver).click();
        info("点击确定按钮...");
        sleep(3000);
        info("等待3秒...");
        Assert.assertTrue(driver.getPageSource().contains("操作成功"));
        Assert.assertTrue(driver.getPageSource().contains("删除中"));
    }

    @AfterClass
    public void afterMethod(){
        driver.quit();
    }
}

方式二:在testng.xml中添加监听

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" preserve-order="true" verbose="2" allow-return-values="true">
    <listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter" />
        <listener class-name="org.uncommons.reportng.JUnitXMLReporter" />
        <listener class-name="util.TestReport"/>
    </listeners>
    <suite-files>
        <suite-file path="testng-spacemanagement.xml"/>
        <suite-file path="testng-mysql.xml"/>
    </suite-files>
</suite>

五、报告样式

原文地址:https://www.cnblogs.com/davieyang/p/10086485.html

时间: 2024-11-05 14:57:39

Java&Selenium&TestNG&ZTestReport 自动化测试并生成HTML自动化测试报告的相关文章

Python&amp;Selenium&amp;Unittest&amp;BeautifuReport 自动化测试并生成HTML自动化测试报告

一.摘要 本篇博文将介绍如何借助BeautifulReport和HTML模版,生成HTML测试报告的BeautifulReport 源码Clone地址为 https://github.com/TesterlifeRaymond/BeautifulReport,其中 BeautifulReport.py和其template是我们需要的关键. 二.BeautifulReport 如下代码是BeautifulReport.py的源码,其中几个注释的地方需要注意,将其集成进自己的自动化框架时需要做相应的

java+Selenium+TestNg搭建自动化测试架构(1)实现代码和数据的分离

1.主要介绍介绍Java+Selenium+POM的自动化测试框架的搭建,第一个首先实现代码和账号URL等信息的分离.第二点支持跨浏览器,通过读取配置文件的方式实现. 1)将账号URL等信息添加在properties文件中然后读取 2)编写浏览器类通过去取配置文件实现浏览器的切换 3)测试浏览器类 项目结构: 1.新建一个文件夹将properties文件放在文件夹中内容如下: # browser switcher #browserName = FirefoxbrowserName = Chrom

java+Selenium+TestNg搭建自动化测试架构(2)实现跨浏览器功能

1.切换浏览器类:其中包含了切换浏览器的方法,以及关闭浏览器,设置等待时间,以及重写的断言方法 package com.rrx.framework; import java.io.IOException;import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium

Mac系统搭建java+selenium+testng环境

Mac系统搭建java+selenium+testng环境: 1.   配置java环境,安装eclipse 2.  离线安装testng插件 3.  配置maven环境 4.  安装谷歌浏览器,下载对应浏览器版本的chromedriver 陆陆续续遇到的一些小问题记录: 1.  testng是使用离线方式安装的,离线包下载地址:http://dl.bintray.com/testng-team/testng-eclipse-release/ 下载完成后将其放到eclipse的dropins文件

Java + Selenium + Appium手机自动化测试

一.启动Android模拟器(Genymotion俗称世界上最快的模拟器,可自行百度安装) 二.启动Appium(Appium环境安装可自行百度) 三.安装应用到Genymotion上,如下图我安装一个计算机的小应用,包名为CalcTest.apk 安装步骤:(基于Android SDK已经配置好了环境变量,可自行百度)1.Win + R2.CMD3.adb devices   --检查操作,列出存在的设置名称4.adb  install  F:\Appium\CalcTest.apk    

Java + Selenium + TestNG + Maven 框架实现Web Automation

环境准备: 1. Java: Install Java jdk: Version: java 1.8 or aboveConfigure Java Environment Variables:Add JAVA_HOMEAdd CLASSPATHAdd to Path Verify Java was configured: Input javac in CMD can get output successfully. 2. Eclipse https://www.eclipse.org/ Unzi

基于Java+Selenium的WebUI自动化测试框架(四)

基于上一篇的内容,这里我们开始写监听类Listener.我这里写监听类的思路是,继承TestListenerAdapter这个类,然后对其中的方法进行重写.网上也有很多资料,建议先学习一下,然后写出来. package webui.xUtils; import org.openqa.selenium.WebDriver; import org.testng.ITestContext; import org.testng.ITestResult; import org.testng.Reporte

基于Java+Selenium的WebUI自动化测试框架(七)--IE浏览器的设置

在上一篇我们讲了关于WebDriver的版本,浏览器初始化,以及下载的设定. 在设置IE浏览器进行WebDriver的测试时,通常会遇见以下几种错误: 1.没有关闭IE浏览器的保护模式. 当运行测试用例后出现类似以下内容的错误: Exception in thread "main" org.openqa.selenium.remote.SessionNotFoundException: Unexpected error launching Internet Explorer. Prot

Java+Selenium Web UI自动化测试的一些小总结

- Chrome 关于Chrome的配置网上信息很多,直说一点,当选择在linux环境跑用例的时候,我们会优先选择headless run,默认情况下headless run的浏览器大小好像只有900*768,我们在windows下调通的用例在缩小的串口下经常会失败,最好调一下size: chromeOptions.setHeadless(true); chromeOptions.addArguments("--no-sandbox"); chromeOptions.addArgume