一:每次运行都需要打开代码工具,如eclipse或者IDE等。为了后面的持续集成,直接使用Maven命令去运行自动化测试,需要引入surfire插件。笔者使用的是2.10版本Surefire和6.9.10版本TESTNG。

下面是项目完整的pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.claire.leafly</groupId><artifactId>projectLemon</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.4.0</version></dependency><!-- https://mvnrepository.com/artifact/org.testng/testng --><dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.9.10</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/dom4j/dom4j --><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>xml-apis</groupId><artifactId>xml-apis</artifactId><version>1.4.01</version></dependency><!-- https://mvnrepository.com/artifact/org.uncommons/reportng --><dependency><groupId>org.uncommons</groupId><artifactId>reportng</artifactId><version>1.1.4</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/com.google.inject/guice --><dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>3.0</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version>
</dependency></dependencies><build><plugins><!-- 1:解决每次右键项目名-maven->update project 时候,项目jdk版本变了,变回1.5版本或者其他版本 2: 解决使用maven编译其他问题:如提示不能在内部类访问外部非final局部变量 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.5.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.10</version><configuration><systemPropertyVariables><org.uncommons.reportng.escape-output>false</org.uncommons.reportng.escape-output>//是否忽略html,解释见下图。与之后在reportNg报告上显示截图相关。</systemPropertyVariables><testFailureIgnore>true</testFailureIgnore>//测试失败后,是否忽略并继续测试<argLine>-Dfile.encoding=UTF-8</argLine><suiteXmlFiles><suiteXmlFile>register.xml</suiteXmlFile>//代表的是要执行的测试套件名称</suiteXmlFiles></configuration></plugin></plugins></build></project>


该配置与reportng相关,后面有详细的解释和源码。

在pom中设置好surefire插件之后,即可使用maven test来执行设置好的测试套件。

注意点(坑):

1.读者使用的各插件或者jar包版本与笔者不同,在执行maventest时,如果未能执行测试套件。请尝试选择不同的suifire插件版本。

2.如上配置的<suiteXmlFile>register.xml</suiteXmlFile>---------------------register.xml该文件一般都放置在根目录下,否则有时会报错

二、在测试完成之后,通常希望得到一份完善的测试报告。TESTNG的测试报告,太过简陋,笔者引入reportNG的jar包。

1.引入reportng依赖

2.在register.xml中,添加监听器NewHtmlReporter,用于渲染reportng 生成的测试报告。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="suitName_register" parallel="false"><test name="testName_register"><classes><!-- <class name="com.demo.auto.claire.testcase.register.Register_FailTester_001" /> --><class name="com.demo.auto.claire.testcase.register.Register_SuccessTester_002" /></classes></test> <!-- Test --><listeners><!-- 添加监听,生成测试报告 --><listener class-name="org.uncommons.reportng.HTMLReporter" />//先添加该监听器,后面添加自定义监听器NewHtmlReporter后,该监听器就可以删掉了<!-- 添加自定义监听,该监听继承了reportNg的 HTMLReporter--> <!-- <listener class-name="com.demo.auto.claire.util.NewHtmlReporter" />--> <!--添加自定义监听器,在测试失败的时候进行截图 --> <listener class-name="com.demo.auto.claire.listener.ListenerFailTestScreenShot"></listener> </listeners> </suite> <!-- Suite -->

注意(坑):

对项目右键–run as --maven test时,如果报Injector类找不到时,需要引入guice依赖。(也可以升级testng的版本,查找到依赖了guice jar的相应版本即可)

三:此时使用reportng生成了测试报告,比testng的要美观一些。但是我们希望可以对其进行定制。

1.显示出每一列的名称

2.显示错误的截图.效果如下:

1.在测试完成之后,需要对失败的用例进行截图。自定义监听器,在测试失败的时候,进行截图。

看一下关于监听的继承和实现关系图

可以看到,ITestListener接口中定义了方法onTestFailure,自定义监听类可以实现改接口,重写该方法。但是,此时需要重写改接口所有的方法。即使方法体里面为空,代码也不会美观。最后笔者选择将自定义监听器继承类TestListenerAdapter,只重写该类中的onTestFailure方法即可。

下面是代码示例:

package com.demo.auto.claire.listener;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;import org.apache.bcel.generic.SIPUSH;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;import com.demo.auto.claire.base.BaseTester;
import com.demo.auto.claire.util.ScreenShotUtil;public class ListenerFailTestScreenShot extends TestListenerAdapter {@Overridepublic void onTestFailure(ITestResult tr) {// 获取到当前的年月日SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");Calendar calendar = Calendar.getInstance();//calendar.getTime()得到的时间是这样的:Fri Aug 31 16:16:51 CST 2018,需要格式化成年月日String time = dateFormat.format(calendar.getTime());//也可以直接使用//String time2 =  dateFormat.format(new java.util.Date()//获得几点周几//SimpleDateFormat dateFormat2 = new SimpleDateFormat("EEEE");//String week = dateFormat2.format(new java.util.Date());// D:\myTest\projectLemon\target\surefire-reports\registertest_register_success_002\2018-08-31String outPutDirectory=tr.getTestContext().getOutputDirectory();//获取到测试的方法名称String methodName= tr.getName();String path1 = outPutDirectory +File.separator+methodName +File.separator+time;/*System.out.println("##################################");System.out.println(path1);System.out.println(outPutDirectory);System.out.println(methodName);*/String imgName=null;try {//当测试不通过的时候,调用截图的代码imgName = ScreenShotUtil.screenShot(BaseTester.driver, path1);} catch (IOException e) {e.printStackTrace();}//Reporter.log("测试代码");//http://localhost:7777/registertest_register_success_002/2018-09-01%E6%98%9F%E6%9C%9F%E5%85%AD/1535807491038.png//String imgHerf2 ="/" +methodName+"/"+ time+"/"+imgName;String suitName = tr.getTestContext().getCurrentXmlTest().getSuite().getName();String imgHerf = "../" +String.join("/",suitName, methodName,time,imgName);//下面这句代码是将截图添加到reportNg的报告中使用的,log的内容会显示在报告上Reporter.log("<img  src='" + imgHerf +"' width='100' height='100'><a href='"+imgHerf+ "' target='_blank'>查看大图</a></img>");
//        System.out.println("******************************");
//        System.out.println(imgHerf);super.onTestFailure(tr);}}

该监听器监听到测试失败之后,会调用截图帮助类中的方法进行截图。

代码示例:

package com.demo.auto.claire.util;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.testng.ITestResult;public class ScreenShotUtil {public static void main(String[] args) {WebDriver driver = SeleniumUtil.getDriver();//driver.get("http://www.baidu.com");//    screenShot(driver);}public static String screenShot(WebDriver driver,String path) throws IOException {File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//String path = sr.getTestContext().getOutputDirectory();//FileUtils.copyFileToDirectory(srcFile, new File(path));//冒号是路径非法字符,路径中不能出现冒号,所以时分秒选择了使用“-”String fileName = (new SimpleDateFormat("HHmmss")).format(new Date())+".png";String pathname = path+File.separator+ fileName ;System.out.println("pathname:"+pathname);FileUtils.copyFile(srcFile, new File(pathname));return fileName;}}

如果是使用maventest执行的测试,则截图存储在target目录下面.(右键test-output,找到同级的target目录-----------surfire-reports ---------------- 套件名称----------- 测试名称 --------------年月日 --------时分秒.png)


如果使用的是testng执行的测试,则截图保存在test-output--------------------surfire-reports ---------------- 套件名称----------- 测试名称 --------------年月日 --------时分秒.png


2.下面讲一下,如何定制reportng

a.修改其配置文件,增加列名



上图中的文本是:(可根据喜好,自行配置)-----修改完成之后,记得托回到jar包中去

log=Log Info
screenshot=Screen Shot
duration=Duration


打开并修改上述文件:


上图中的文本是:-----修改完成之后,记得托回到jar包中去

#if ($failedTests.size() > 0)<table class="resultsTable"><tr><th colspan="4" class="header failed">$messages.getString("failedTests")</th></tr>#foreach ($testClass in $failedTests.keySet())<tr><td colspan="1" class="group">$testClass.name</td><td colspan="1" class="group">$messages.getString("duration")</td><td colspan="1" class="group">$messages.getString("log")</td><td colspan="1" class="group">$messages.getString("screenshot")</td></tr>#set ($classResults = $failedTests.get($testClass))#parse ("org/uncommons/reportng/templates/html/class-results.html.vm")#end</table>
#end

上面两步,完成了给测试失败的用例,添加3个列名。


接下来修改源码和模板文件,将截图添加进入。

在上述的测试失败进行截图的监听器中,有一句代码是这样的


reporter.log(“XXX”)-------这个xxx的内容就会显示在我们的Log info列。---------------下一步,就是要将图片从log info列删除,在screen shot列添加:


打开该指定文件。


上图文本为:

## Show logger output for the test.#set ($output = $utils.getTestOutput($testResult))#if ($output.size() > 0)<div class="testOutput">#foreach( $line in $output )#if ($meta.shouldEscapeOutput())$utils.escapeHTMLString($tools.removeImage($line))<br />#else$tools.removeImage($line)<br/>#end#end</div>#end


上图文本为:

<td class="screenshot">## Show logger output for the test.#set ($output = $utils.getTestOutput($testResult))#if ($output.size() > 0)<div class="screenshotimage">#foreach( $line in $output )#if ($meta.shouldEscapeOutput())$utils.escapeHTMLString($tools.getImageString($line))<br />#else$tools.getImageString($line)<br/>#end#end</div>#end</td>

可以看到,上面试使用tools.getImageString() 、tools.removeImage来获取和删除图片的。这个tools是哪里来的呢?

我们看到reportng自己的方法都是使用的

这个util的对象是从哪里注册进来的?



可以看到HTMLreporter继承了AbstractReporter,AbstractReporter中定义了一个final的常量UTILS----引用指向的是ReportNGUtils对象,该ReportNGUtils定义了各种方法,供模板文件中调用。又通过creatContext的方式注册进模板文件(VelocityContext)对象中。

那么想要在模板文件中删除和加上图片,有2种方式,

第一:修改ReportNGUtils类,在其中加上删除和引入图片的方法。会涉及到修改源码,修改源码通常也有2种方式:

1.下载源码,修改,完成后重新打jar包并引入------------操作起来比较麻烦

2.在自己的项目下,生成一个与reportng一致的包名和类名(org.uncommons.reportng.HTMLReporter.class),在其中修改代码。----------这样的话,如果别人引入了你的jar包又引入了reportng的jar包,要考虑下到底使用的谁的。

第二:自定义一个NewHtmlReporter,去继承HTMLReporter,重写父类的creatContext方法,将自己的工具类引入。

下面是NewHtmlReporter 的源码

package com.demo.auto.claire.util;import org.apache.bcel.generic.NEW;
import org.apache.velocity.VelocityContext;
import org.uncommons.reportng.HTMLReporter;public class NewHtmlReporter extends HTMLReporter{private static final ReportNgTools TOOLS = new ReportNgTools();@Overrideprotected VelocityContext createContext() {VelocityContext context = super.createContext();context.put("tools", TOOLS);return context;}}

下面是自己实现了删除和增加截图的工具类ReportNgTools源码:

package com.demo.auto.claire.util;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class ReportNgTools {public String sayHello() {return "love";         }public String removeImage(String log) {//正则表达式String regex = "<img .*>.*</img>";//匹配到正则的内容,将其用空字符替换return log.replaceAll(regex, "");}public String getImageString(String log) {//正则表达式String regex = "<img .*>.*</img>";//将正则表达式编译为Pattern对象Pattern pattern = Pattern.compile(regex);//通过正则表达式对象去匹配log内容Matcher matcher = pattern.matcher(log);//如果匹配到了,则返回第0组(第0组是包含了所有匹配到的数据)if (matcher.find()) {return matcher.group(0);}//否则返回空return "";}}

此时,我们直接引入自己的监听即可:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="suitName_register" parallel="false"><test name="testName_register"><classes><!-- <class name="com.demo.auto.claire.testcase.register.Register_FailTester_001" /> --><class name="com.demo.auto.claire.testcase.register.Register_SuccessTester_002" /></classes></test> <!-- Test --><listeners><!-- 添加监听,生成测试报告。这个就可以删除了 --><!-- <listener class-name="org.uncommons.reportng.HTMLReporter" /> --><!-- 添加自定义监听,该监听继承了reportNg的 HTMLReporter--><listener class-name="com.demo.auto.claire.util.NewHtmlReporter" /><!--添加自定义监听器,在测试失败的时候进行截图  --><listener class-name="com.demo.auto.claire.listener.ListenerFailTestScreenShot"></listener></listeners>
</suite> <!-- Suite -->

综上就完成了关于reportng定制的部分

地址:https://www.cnblogs.com/clairejing/p/9581704.html

自动化测试--实现一套完全解耦的简单测试框架(二)相关推荐

  1. 自动化测试--实现一套完全解耦的简单测试框架

    selenium中有提供pageObject,支持将页面元素和动作单独封装到一个类中. 但是,当页面元素发生变化的时候(在项目的维护过程中,很很容易发生的),就需要去修改源代码.为了解决这个问题,可以 ...

  2. 【Java 注解】自定义注解 ( 使用注解实现简单测试框架 )

    文章目录 一.定义注解 二.使用注解 三.解析注解 在 [Java 注解]自定义注解 ( 注解属性定义与赋值 ) 博客中讲解了 注解属性 ; 在 [Java 注解]自定义注解 ( 元注解 ) 博客中讲 ...

  3. Java注解案例-简单测试框架

    目录 一.需求 Calculator类: Check注解: TestCheck类: 二.运行结果 控制台: 记录异常的文件(bug.txt): 三.结论 一.需求 需求:当主方法执行后,会自动执行被检 ...

  4. 自动化测试--实现一套完全解耦的测试框架(三)

    之前博客中已经将笔者实现的框架进行过简单介绍,在使用过程中,对以下几点提出优化: 1.页面URL和页面的定位信息保存不同的配置文件中-----------整合到一个配置文件中,相应的配置文件解析做出调 ...

  5. 关于Android的自动化测试,你需要了解的5个测试框架

    Appium Appium是一个开源的移动测试工具,支持iOS和Android,它可以用来测试任何类型的移动应用(原生.网络和混合).作为一个跨平台的工具,你可以在不同的平台上运行相同的测试.为了实现 ...

  6. MQTT——java简单测试(二)

    服务端代码: import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttC ...

  7. Java运用注解反射编写简单测试框架

    测试一个计算器类,把异常类型次数其他异常信息自动生成BUG文件 /*** 计算器类*/ public class Calculator {//加法@Checkpublic void add(){Sys ...

  8. 什么是python自动化测试_python已经自动化了,大家一般用什么测试框架?

    首先我们需要明白自动化测试框架更倾向于一种设计思想 ,这种思想指导工具的使用或者自研开发,并且不是只能使用仅仅一种框架,结合被测系统本身特性一般是选择多种测试框架的组合,来满足测试和设计需求(开发.维 ...

  9. 设计自己的基于Selenium 的自动化测试框架-Java版(1) - 为什么selenium还需要测试框架?...

    本人自动化测试接触时间不久,如有误导,概不负责. 既然有了selenium这个开源的自动化的工具,为什么还要我们自己再去写一个框架? Selenium是自动化的工具,当然是可以用在测试领域,但他不是为 ...

最新文章

  1. 解析CleanMyMac隐私保护内容与使用
  2. 大数据时代的网络视频营销
  3. WebStorm React JS语法报错问题
  4. 推荐系统实践整体化总结
  5. 第一周周日DailyReporting——PM(李忠)
  6. CF1572B. Xor of 3
  7. mysql何时会走索引
  8. 为什么java什么意思_java – 什么意思是immutable?
  9. python—将自定义函数的路径添加到系统路径中
  10. CreateThread _beginThread _begintheadex AfxBeginThead思考
  11. Nginx反向代理的目录访问问题
  12. openstack-O版-glance安装
  13. Atitit 学习方法 -------体系化学习方法 Excel 科目,分类,专业 三级分类。。 知识点。。 课程就是每一个知识点的详细化。。 比如经济学 类别 专业 xx概论知识点 3、金
  14. 为什么仿宋字体打印出楷体_win7仿宋字体及楷体字体打包下载
  15. 惠普打印机只打印一半_打印机打印一半字就只有半个了
  16. win7计算机打开显卡设置在哪里,win7在哪里打开显卡设置
  17. 十一种常见的光纤网络传输方案
  18. 国内外对于GaN中Fe相关点缺陷结构的局域特性的研究进展
  19. U盘检测-linux+QT
  20. 5:Echarts数据可视化-多条曲线、多个子图、TreeMap类似盒图、树形图、热力图、词云...

热门文章

  1. Nginx+Lua 积累
  2. linux初始化进程
  3. [转]30个自我提升技巧
  4. 如何才干创建一个空的IBM DB2 ECO数据库
  5. Leetcode 109
  6. 四、Angular新建组件和使用
  7. ZBrush常用快捷键
  8. ZBrush中的Clip剪切笔刷怎么快速运用
  9. 解决phpmailer可以在windows下面发送成功, 在linux下面失败的问题
  10. Java:使用 Java 开发的一个异常处理框架