基于WebDriver&TestNG 实现自己的Annotation @TakeScreenshotOnFailure

Jenkins + TestNG 实现自助式自动化测试平台 摘要: 本文介绍了如何使用 Jenkins 和 TestNG 实现满足复杂测试需求的”自助式”自动化测试平台。该方案以 Jenkins 作为平台的基础,结合功能强大的插件及系统配置,部署基于 TestNG 的自动化测试包,并提供了友好的 Web 访问界面。项目成员可以在任何时间和地点,通过浏览器访问该平台,而且可以按照不同需求选择测试环境、测试集、测试用例,并提交自动化测试请求,达到真正的“自助式 阅读详情

相信用过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 都不会截屏。

Webdriver+Testng实现测试用例失败自动截图功能 在自动化测试中,如果有测试用例运行失败,我们想到使用截图方式对页面出问题的现场进行“照相”,方便后继的问题排查。 1.定义一个截图类实现具体的截图操作: package ec.qa.autotest.ui.testng.listener; import java.io.File; import java.io.IOException; import java.lang.reflect 阅读详情

相关推荐

Jenkins实现持续集成中的那些坑

小伙伴在《这些年我们一起搞过的持续集成~Jenkins+Perland Shell script》中详细介绍了优化后的job流,接下来总结一下在构建这一套job中遇到的Shell  Script和Jenkins的问题。 1.      比较两个文件后有特殊字符 解决方法:过滤特殊字符 -------------1) [annzan@vm10226address]$ diff curre

chndata的专栏 2万+

Java+Selenium3方法篇30-Selenium中截图方法-TakeScreenshot

前面几篇介绍了Actions类中两种方法,本来打算介绍右键,然后类似点击向下箭头这样操作,但是在现在的firefox和chrome都不能正常实现,记得之前selenium2.53是可以在firefox上实现的。本篇介绍Selenium中截图类TakeScreenshout,这个类主要是获取浏览器窗体内的内容,不包括浏览器的菜单和桌面的任务栏区域,我们用百度首页来截图,看看截图效果。       

Anthony_tester的博客 1万+

开源内存数据库H2 实现单元测试用例的独门独户

背景 部门逐渐规范代码质量,要求单元测试用例代码覆盖率要达到50%,所以最近大家渐渐养成了写单元测试用例的习惯。由于系统功能主要就是增删改查,所以当大家的单元测试用例使用同一个数据库时发生数据冲突,经常造成单元测试不通过的情况,影响了代码进度。所以对于每一个测试用例需要一个独立的数据库,这时候Lu同学经过研究发现了h2内存数据库,解决了之前的问题。   简介 H2是一个开源的内存数据库,支

chndata的专栏 5180

testng对失败时截图处理

1.截图类: 1 public class ScreenShot { 2 public WebDriver driver; 3 4 public ScreenShot(WebDriver driver) { 5 this.driver = driver; 6 } 7 8 private void ...

aohuijie9022的博客 284

玩转单元测试之WireMock -- Web服务模拟器

WireMock 是一个灵活的库用于 Web 服务测试,和其他测试工具不同的是,WireMock 创建一个实际的 HTTP服务器来运行你的 Web 服务以方便测试。 它支持 HTTP 响应存根、请求验证、代理/拦截、记录和回放, 并且可以在单元测试下使用或者部署到测试环境。 它可以用在哪些场景下: 测试移动应用依赖于第三方REST APIs创建快速原型的APIs注入否则难于模拟第

chndata的专栏 3287

Blender - Shrinkwrap - 更方便的制作贴合模型的表面来建模

Shrinkwrap 修改器 使用 Blender 想要快速建模可以贴合现有模型表面的效果:衣服、皮肤、等效果,可以使用 Shrinkwrap 修改器,这个修改器的名字其实按照英文上的理解,翻译为:收缩的包裹效果 应用 如这块铁皮,它要贴合机身弯曲的效果,可以先建好一个铁皮,再 Shrinkwrap 到一个指定的网格上 留意的参数 Target 要贴合的对象(目前我已知是可以贴合到网格对象上,实在是方便) VertexGroup 顶点组,和之前讲到过的,顶点组可以组设顶点的权重,意思这个可.

Jave.Lin 的学习笔记 6070

Java+Selenium——截图方法-TakeScreenshot——保存到桌面——TakeScreenshot截图只针对浏览器的web事件...

package rjcs; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Set; import org.openqa.selenium.interactions.Actions...

小白龙白龙马的博客 750

软件缺陷(定义+表现形式+优先级+信息+产生原因),看完这篇文章就懂了

软件缺陷软件缺陷的定义软件缺陷的表现形式软件缺陷产生的原因软件缺陷的根源软件缺陷的费用软件缺陷的信息 软件缺陷的定义 IEEE 1983 of IEEE Stardard 729中软件缺陷做了一个标准的定义: 从产品内部看,软件缺陷是软件产品开发或维护过程中所存在的错误、毛病等各种问题;从外部看,软件缺陷是系统所需要实现的某种功能的失效或违背。 因此软件缺陷就是软件产品中所存在的问题,最终表现为用户所需要的功能没有完全实现,没有满足用户的需求。 缺陷不是bug,缺陷包含bug,缺陷的范围更大。 软件缺陷

qq_40676418的博客 1万+

python selenium 框架_python + selenium 自动化测试框架

分享一个网站自动化测试框架结构如下:test_project|--logs|---pages|---register_page.py| |---base_page.py|---test_case|---web_test_case|---test_register.py| |---base.py|---utilities|---conn_db.py|---conn_redis.p...

weixin_39553904的博客 276

802.11 NDP Sounding

NDP Sounding1.NDP原理2.NDP 过程3.帧结构3.1 NDPA结构3.2 CBF帧 1.NDP原理 802.11n标准提供的波束成形技术,可以通过预先补偿发射天线的相位,让两条波束进行叠加以实现最好的效果 显式波束成形需要终端反馈信道信息: AP向STA发送探测数据(NDP: null data packet sounding) STA向AP反馈信道信息(Compressed beamforming) AP根据STA的反馈或自行计算的权重信息进行波束成形 2.NDP 过程 802.

weixin_45799954的博客 8262

mysql9.0windows安装

将这里的位置修改为你刚刚创建并复制data目录的地址即可,win11的系统使用vscode修改之后,会让你确认开启更高权限以进行保存,比较方便,window10不需要确认,修改后可以直接保存。:在修改之前,最好将下图文件进行备份,将原始的文件保存好一份,以防更改了配置之后,导致mysql服务报错,无法启动,备份好的话直接将有问题的配置文件给替换就可以,无需重新安装一次mySql。双击下载的msi文件进行安装。安装有问题的,可以直接进行卸载,新本的mySql会将注册表中的数据自动进行清除,还是很方便的。

m0_74824123的博客 6445

selenium(java)利用testng监听test运行失败时截图

目录如下所示 TestIms 类中有两个测试方法 @Listeners({TestngListenerScreenshot.class}) public class TestIms extends baseDriver{ @Test //打开首页 public void openPage(){ //System.setProperty("webdriver.chrom.driver", "D...

weixin_38102592的博客 835

【YOLOv8实战】从零构建番茄成熟度智能检测GUI系统【附完整工程】

本文详细介绍了从零构建基于YOLOv8的番茄成熟度智能检测GUI系统的完整实战流程。内容涵盖环境搭建、数据集准备、模型训练调优,并重点讲解如何使用PyQt5开发图形界面,最终将项目打包为可执行文件,实现AI模型从训练到桌面应用落地的完整工程闭环。

xxx12的博客 821

selenium+testng+java testng扩展,监听器中加入用例失败后截图功能

写好截图方法 import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.openqa.selenium.OutputType; i...

aiee的博客 2006

记一次springboot集成海康威视SDK过程

一开始没有接触过物联网这块,走了很多弯路,后面还是自己一点点摸索出来的。有个项目,需要对海康的门禁设备进行集成,后台统一管理设备,进行设备人脸数据的下发、删除等操作。3.我还接入了门禁设备的事件监听,门禁所有的事件都会上报到后台服务,这块代码有需要的可以找我。在linux系统中,sdk我使用的是绝对路径,把Linux版本的文件放到服务时,Acs文件夹下的 各个Manage都有现成的代码,可以根据自己的需要调用即可。路径也不要有中文,切记!2.sdk的存放路径不要有中文,不然会出现很多奇怪的问题。

huang_xiaoen的博客 2348

C++程序发生内存越界,一定会导致程序崩溃吗?详解内存越界

内存越界是否一定会导致程序崩溃吗?详解内存越界

dvlinker的技术专栏 1万+

selenium截图(Take a screenshot with Selenium WebDriver)

地址:http://stackoverflow.com/questions/3422262/take-a-screenshot-with-selenium-webdriver Java Yes, it is possible. The following example is in Java: WebDriver driver = new Fire

2446

我的世界进阶模组开发教程——制作机械动力附属模组

摘要: Create是Minecraft的机械动力模组,其代码结构分为多个关键模块: 数据生成系统:通过CreateRecipeProvider基类实现配方自动化生成,支持多步骤序列化装配配方(SequencedAssemblyRecipeGen),采用建造者模式链式调用; 注册管理:CreateRegistrate扩展了Registrate库,统一管理方块、流体、实体等注册,集成标签页分类和工具提示定制; 伤害系统:DamageTypeTagGen为机械伤害(如钻头、风扇火焰)定义原版兼容的标签; 客户端

qq_24992377的博客 2083

jmeter执行脚本并生成测试报告时报错:Results file:result.jtl is not empty

jmeter:5.1.1 操作系统:Win10 重现步骤:今天想通过命令执行jmeter的脚本并生成HTML测试报告,第一次执行没有问题,第二次执行的时候报错:Results file:result.jtl is not empty。于是开始了百度的大海捞针。终于找到了一篇文章与我的情况相符,决定详细记录一下。 解决方法:jmeter每次执行时,会在bin目录下生成result.jtl,删除即可。 -------------------------------------------------

hzx18022464374的博客 4778

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

使用WebDriver遇到的那些坑

在做web项目的自动化端到端测试时主要使用的是Selenium WebDriver来驱动浏览器。Selenium WebDriver的优点是支持的语言多,支持的浏览器多。主流的浏览器Chrome、Firefox、IE等都支持,手机上的浏览器Android、IPhone等也支持,甚至还支持PhantomJS(由于PhantomJS跑测试时并不需要渲染元素,所以执行速度快)。 ...

weixin_34174322的博客 422

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

实现Selenium Webdriver自动化测试中对失败测试进行截图并发布到Jenkins

在基于Selenium Webdriver(Java) + Junit4 + Jenkins 的web 自动化测试中,进行失败test的截图,同时发布到Jenkins上。 这两天在研究这个问题,这是一点总结,首先需要版本够高的Jenkins,并安装Junit Attachments plugin,同时注意要去Jenkins配置 Additional test report features,选择...

python012的专栏 1343

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Selenium WebDriver 自动化测试截图问题

// Selenium Client: selenium-java-2.34.0   在 Selenium WebDriver 测试脚本中添加截图功能,可以使用以下2种方法:  (1) TakesScreenshot (org.openqa.selenium.TakesScreenshot) File srcFile = ((TakesScreenshot) driver)

blog.title = "Hello world"; 3786

使用Selenium Webdriver进行全屏截图

在任何网页测试人员中,执行效果最好的操作之一就是对网页进行截图。 每当测试人员发现并报告错误时,如果不支持该问题的屏幕截图甚至视频,就不会认真对待该错误。 不论您进行的测试类型是什么,包括硒自动化测试,都是如此。 在自动化测试中,特别是在典型的测试运行可能涉及数百个命令和测试用例的情况下,关键断言处的自动屏幕截图对于确保开发人员和测试人员确保按需执行每个测试用例都非常重要。 这些证明又被...

最佳 Java 编程 2783

使用TestNg 测试框架时自动化测试失败重试解决方案

自动化测试时,有时会因为网络不稳定,或者测试环境、第三方环境正在重启而造成用例运行结果不稳定,导致时而能测试通过时而又不通过的测试用例。这些难以重现的环境因素造成的用例失败,经常会耗费排查时间,然而又没有太多改善的空间。针对这种情况,可以基于TestNG的重试器和监听器实现失败结果的重试和监听,一旦监听到失败的测试用例,启动定制的重试方法和处理方法来实现重新运行。 IRetryAnalyzer实...

Sundy_sc的专栏 1670

WebDriver测试失败后自动获取截图

UI自动化测试其实并不是那么稳定,可能是因为UI元素的改动,也可能是因为网络的不稳定,在测试失败的时候,WebDriver通常会抛出一些异 常;通过异常信息通常都能知道大概是哪里出错了,但是如果能加上截屏,那就更加好了。尤其是用Remote WebDriver运行测试,所有测试都是通过Selenium Grid分发到各个节点来运行,不同节点的配置还有可能不是完全一样。 如果是使用RemoteWe...

weixin_33895516的博客 432

技术那么多,你想看看JSON Schema的测试吗?

目录 1. 什么是JSON Schema? 2. 如何定义一个JSON Schema 3. 如何测试JSON Schema a) 使用JSON Schema validator GUI b) 在Java code里使用JSON Schema validator 4.参考文档   什么是JSON Schema? JSON模式是基于JSON格式定义J

chndata的专栏 2666
上一篇: 《实体解析与信息质量》 - 4.1.1 介绍
下一篇: 开源内存数据库H2 实现单元测试用例的独门独户
数据中国
博客等级 码龄12年 136粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值