基于WebDriver&TestNG 实现自己的Annotation @TakeScreenshotOnFailure
相信用过Selenium WebDriver 的朋友都应该知道如何使用WebDriver API实现Take Screenshot的功能。
在这篇文章里,我主要来介绍对failed tests实现 take screenshot的功能, 并且我们也高大上一回,做成注解的形式。
效果如下:


目录
前提
Maven 配置
Example
简单类图
TakeScreenshotOnFailure
CustomTestListener
WebDriverHost
TestBase
DemoListenerTest
TestNG.xml
Run as TestNG
前提
- JDK 1.7
- Maven 3
Maven 配置
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.5</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.46.0</version>
</dependency>
Example
简单类图

首先创建一个类 如下 TakeScreenshotOnFailure.java
package test.demo; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* Annotation informs CustomTestListener to take screenshot if test method fails. File name is method name + png suffix.
* Test class must implement WebDriverHost in order for the screenshot to work.
*
* @author wadexu
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value =
{ElementType.METHOD})
public @interface TakeScreenshotOnFailure {
}
##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html
然后创建一个自己的CustomTestListener 继承TestNG 的 TestListenerAdapter 重写onTestFailure()方法, 加入take screenshot的功能
代码如下
package test.demo; import java.io.File;
import java.lang.reflect.Method; import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver; import org.testng.ITestResult;
import org.testng.TestListenerAdapter; /**
*
* @Description: A custom test listener extends TestListenerAdapter for take screen shot on failed test case.
* @author wadexu
*
* @updateUser
* @updateDate
*/
public class CustomTestListener extends TestListenerAdapter { private static String fileSeperator = System.getProperty("file.separator");
protected static final Logger logger = Logger.getLogger(CustomTestListener.class); @Override
public void onTestFailure(ITestResult result) {
super.onTestFailure(result);
Object o = result.getInstance();
WebDriver driver = ((WebDriverHost) o).getWebDriver(); Method method = result.getMethod().getConstructorOrMethod().getMethod();
TakeScreenshotOnFailure tsc = method.getAnnotation(TakeScreenshotOnFailure.class); if (tsc != null) {
String testClassName = getTestClassName(result.getInstance().toString()).trim(); String testMethodName = result.getName().toString().trim();
String screenShotName = testMethodName + ".png"; if (driver != null) {
String imagePath =
".." + fileSeperator + "Screenshots" + fileSeperator + "Results"
+ fileSeperator + testClassName + fileSeperator
+ takeScreenShot(driver, screenShotName, testClassName);
logger.info("Screenshot can be found : " + imagePath);
}
}
} /**
* Get screen shot as a file and copy to a new target file
*
* @Title: takeScreenShot
* @param driver
* @param screenShotName
* @param testClassName
* @return screenShotName
*/
public static String takeScreenShot(WebDriver driver,
String screenShotName, String testClassName) {
try {
File file = new File("Screenshots" + fileSeperator + "Results");
if (!file.exists()) {
logger.info("File created " + file);
file.mkdir();
} File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File targetFile = new File("Screenshots" + fileSeperator + "Results" + fileSeperator + testClassName, screenShotName);
FileUtils.copyFile(screenshotFile, targetFile); return screenShotName;
} catch (Exception e) {
logger.error("An exception occured while taking screenshot " + e.getCause());
return null;
}
} /**
* Get a test class name
*
* @Title: getTestClassName
* @param testName
* @return testClassName
*/
public String getTestClassName(String testName) {
String[] reqTestClassname = testName.split("\\.");
int i = reqTestClassname.length - 1;
String testClassName = reqTestClassname[i].substring(0, reqTestClassname[i].indexOf("@"));
logger.info("Required Test Name : " + testClassName);
return testClassName;
} }
接口类 WebDriverHost
package test.demo; import org.openqa.selenium.WebDriver; /**
* Class implementing that interface is expected to return instance of web driver used in last test method.
*
* @author wadexu
*/
public interface WebDriverHost { /**
* Returns instance of web driver used in last test method.
*
* @return WebDriver
*/
public WebDriver getWebDriver();
}
##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html
测试基类TestBase
package test.demo; import java.io.File;
import java.io.IOException; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; /**
* @Description: Abstract test base class, Test class must extends this class.
* Initialize a firefox webDriver for tutorial purpose only.
* @author wadexu
*
* @updateUser
* @updateDate
*/
public abstract class TestBase implements WebDriverHost{ protected WebDriver webDriver = null; @Override
public WebDriver getWebDriver() {
return webDriver;
} @BeforeClass
public void setUp() throws IOException {
FirefoxProfile firefoxProfile = new FirefoxProfile();
// use proxy
firefoxProfile.setPreference("network.proxy.type", 1);
firefoxProfile.setPreference("network.proxy.http", "10.51.1.000");
firefoxProfile.setPreference("network.proxy.http_port", "8080"); //get rid of google analytics, otherwise it's too slow to access to cnblogs website
firefoxProfile.addExtension(new File(getClass().getClassLoader().getResource("no_google_analytics-0.6-an+fx.xpi").getFile())); webDriver = new FirefoxDriver(firefoxProfile);
} @AfterClass
public void tearDown() {
webDriver.close();
} }
DemoListenerTest 测试类
package test.demo; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; /**
* @Description: Demo a Test using custom Test Listener with an annotation TakeScreenshotOnFailure
* @author wadexu
*
* @updateUser
* @updateDate
*/
public class DemoListenerTest extends TestBase{ @Test
@TakeScreenshotOnFailure
public void testFail() {
webDriver.get("http://www.cnblogs.com/"); //Fail this test method for tutorial purpose only
assertTrue(false);
} }
TestNG 的 xml 文件 配置如下,加入listener监听
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!--<suite name="DMP_Test_Suite" -->
<suite name="Demo_Test_Suite" parallel="false">
<listeners>
<listener class-name="test.demo.CustomTestListener" />
</listeners>
<test name="Demo_Test">
<classes>
<class name="test.demo.DemoListenerTest" />
</classes>
</test>
</suite>
##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html
Run as TestNG
断言故意错误 让test fail

控制台输出
2015-10-08 15:04:29,896 INFO [test.demo.CustomTestListener] - Required Test Name : DemoListenerTest
2015-10-08 15:04:31,985 INFO [test.demo.CustomTestListener] - Screenshot can be found : ..\Screenshots\Results\DemoListenerTest\testFail.png
图片以测试方法命名, 存在含类名的路径下

测试方法Pass 或者 fail但没加Annotation 都不会截屏。
感谢阅读,如果您觉得本文的内容对您的学习有所帮助,您可以点击右下方的推荐按钮,您的鼓励是我创作的动力。
##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html
基于WebDriver&TestNG 实现自己的Annotation @TakeScreenshotOnFailure的更多相关文章
- 基于webdriver的jmeter性能测试-通过jmeter实现jar录制脚本的性能测试
续接--基于webdriver的jmeter性能测试-Eclipse+Selenium+JUnit生成jar包 在进行测试前先将用于支持selenium录制脚本运行所需的类包jar文件放到jmeter ...
- linux搭建phantomjs+webdriver+testng+ant自动化工程
因为项目的原因,需要将脚本在linux环境无浏览器化去跑,那么原有的在windows系统下有浏览器化的自动化脚本场景就不适用了,这里给出linux系统下搭建phantomjs+webdriver+te ...
- selenium webdriver testng自动化测试数据驱动
selenium webdriver testng自动化测试数据驱动 selenium webdriver testng自动化测试数据驱动 一.数据驱动测试概念 数据驱动测试是相同的测试脚本使用不同的 ...
- 基于 webdriver 的测试代码日常调试方python 篇
看到论坛有人写了JAVA的测试代码日常设计,就给大家分享一下偶自己平时是如何测试测试代码的.主要基于python语言.基于 webdriver 的日常调试在 python交互模式下非常方便,打开pyt ...
- nightwatch 基于Webdriver的端到端自动化测试框架
nightwatch 是使用nodejs编写的,基于Webdriver api 的端到端自动化测试框架 包含以下特性 清晰的语法,基于js 以及css 还有xpath 的选择器 内置测试runner, ...
- Guiceberry+Webdriver+TestNG
1. Guiceberry Leverage Guice to achieve Dependency Injection on your JUnit tests https://code.google ...
- Selenium WebDriver TestNg Maven Eclipse java 简单实例
环境准备 前提条件Eclipse 已经安装过 TestNg ,Maven 插件 新建一个普通的java项目 点击右键 configure->convert to Maven Project 之后 ...
- Webdriver+testNG+ReportNG+Maven+SVN+Jenkins自动化测试框架的pom.xml配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- Webdriver+Testng实现测试用例失败自动截图功能
testng执行测试用例的时候,如果用例执行失败会自动截图,方便后续排查问题 1.首先定义一个截图类: package com.rrx.utils; import java.io.File;impor ...
随机推荐
- ubuntu 非常简单的方式安装多个perl版本
参考http://stackoverflow.com/questions/22934080/how-to-downgrade-to-perl-5-10-1 Perlbrew will allow yo ...
- div各种距离 详细解释图
详细博文介绍:http://blog.csdn.net/fswan/article/details/17238933
- JavaScript,DOM经典基础面试题
JavaScript的数据类型 JavaScript的数据类型可以分为原始类型和对象类型 原始类型包括string,number和Boolean三种,其中字符串是使用一对单引号或者一堆双引号括起来的任 ...
- 《C#编程宝典:十年典藏版》阅读笔记(1)
1.运行时错误,使用Checked块语句进行异常检查与抛出异常. 2.值类型使用线程堆栈保存数据,数据大小大概为1M左右,引用类型使用托管堆保存数据,可以无限分配空间,因为有一个GC垃圾回收机制存在, ...
- iOS开发ARC内存管理技术要点
本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...
- 浅谈P NP NPC
P问题:多项式时间内可以找到解的问题,这个解可以在多项式时间内验证. NP问题:有多项式时间内可以验证的解的问题,而并不能保证可以在多项式时间内找到这个解. 比如汉密尔顿回路,如果找到,在多项式时间内 ...
- centos x86_64环境下 下载chrome
由于Cent OS内核版本过低,无法安装Chrome浏览器2.替代方案:可以使用Chromium浏览器 1.切换到root: su - 或者 sudo -i 2.下载新的软件源定义: cd /etc/ ...
- 十分钟搞定微信企业帐号“echostr校验失败,请您检查是否正确解密并输出明文echostr”
问题域:在这里我们只解决密文可以正确解密,但微信验证提示“echostr校验失败,请您检查是否正确解密并输出明文echostr”的问题. 干货:没有正确验证的原因是:你给微信返回的是字符串,而微信需要 ...
- Ext.Net 学习随笔 002 默认按钮
在FormPanel中按回车按键,会触发默认按钮的click事件.设置方法为在FormPanel中设置DefaultButton属性,如果没有设置这个属性,默认为最后一个按钮. 1.缺省最后一个按钮为 ...
- 印刷电路板(PCB)的材料
以玻璃为基础材料的板材可以在高达150℃到250℃的温度下使用.可选的介质材料有: FR4,介电常数ε0为4.6 环氧材料,介电常数ε0为3.9: 聚酰亚胺,介电常数ε0为4.5. 另外,以聚四氟乙烯 ...