使用appium和testng实现Android自动截图
简单介绍
需求场景是:当测试安卓应用的脚本得到失败结果时,对当前手机屏幕截图,便于查找问题。
实现方式是:1)定义一个父类UITest,作为所有测试类的父类。在父类中UITest中定义一个截图的方法,所有的子类就都可以使用这个方法了。2)实现testng的ITestListener接口,参考这里,在这个接口的onTestFailure方法中调用测试类的截图方法。
定义测试脚本的父类
package main.java.com.dbyl.library.utils; /**
* Created by wwh on 17/2/16.
*/
/**
*
*/ import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; import io.appium.java_client.android.AndroidDriver;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot; /**
* @author
*
*/
public class UITest {
private AndroidDriver driver;
Log log = new Log(this.getClass()); public AndroidDriver getDriver() {
return driver;
} /**
* init test case
*
* @param driver
*/
public void setDriver(AndroidDriver driver) {
this.driver = driver;//把子类的driver传进来,更新父类driver
} public void init(AndroidDriver driver) {
setDriver(driver);
} /**
* take screenshot
*/
public void takeScreenShot() {
SimpleDateFormat sf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
String dateStr = sf.format(date);
String path = this.getClass().getSimpleName() + "_" + dateStr + ".png";//用类名和日期作为截图的文件名
takeScreenShot((TakesScreenshot) this.getDriver(), path);
} /**
* take screenshot
* @param drivername
* @param path
*/
public void takeScreenShot(TakesScreenshot drivername, String path) {
// this method will take screen shot ,require two parameters ,one is
// driver name, another is file name log.info("take screenshot");
File scrFile = drivername.getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy
try {
log.info("save snapshot path is:" + path);
FileUtils.copyFile(scrFile, new File( path));
} catch (Exception e) {
log.error("Can't save screenshot");
e.printStackTrace();
} finally {
log.info("screen shot finished");
}
} }
上面代码中,使用了AndroidDriver类型的driver,适用于安卓应用测试脚本的父类。如果测试iOS应用,则使用iOSDriver类型的driver。
继承父类的测试脚本
package main.java.com.dbyl.library.utils;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.Assert;
import org.testng.annotations.*; import java.io.File;
import java.net.URL; /**
* Created by wwh on 17/2/20.
*/
@Listeners(main.java.com.dbyl.library.utils.CustomTestngListener.class)//通过注解调用我们自己实现的类
public class TestScreenshot extends UITest{//继承父类UITest
private AndroidDriver<MobileElement> driver; @Test
public void Demo() throws Exception {
// set up appium
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.APPIUM);
//for native app set null, for web test please set chrome or firefox
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator");
//simulator version 4.4
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "4.4");
// if no need install don't add this
File classpathRoot = new File("/Users/wwh/IdeaProjects");
// File classpathRoot = new File(System.getProperty("user.dir"));
File appDir = new File(classpathRoot, "apps");
File app = new File(appDir, "apppiumDemo.apk");
capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); //package name
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "cn.dbyl.appiumdemo");
// // support Chinese
capabilities.setCapability("unicodeKeyboard", "True");
capabilities.setCapability("resetKeyboard", "True");
// no need sign
capabilities.setCapability("noSign", "True");
//launcher activity
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".MainActivity");
String url = "http://localhost:4723/wd/hub";
driver = new AndroidDriver<MobileElement>(new URL(url), capabilities);
super.init(driver);//在driver赋值后,需要将driver传给父类。 MobileElement text = driver.findElementById("cn.dbyl.appiumdemo:id/text11");//这里将ID值由text1改为text11,所以这一句会报错
Assert.assertEquals(text.getText(), "appiumDemo"); MobileElement button = driver.findElementByClassName("android.widget.Button");
button.click();
text = driver.findElementById("cn.dbyl.appiumdemo:id/text1");
Assert.assertEquals(text.getText(), "You just click the button"); } @AfterTest
public void Teardown(){
driver.quit();
} }
TestListenerAdapter类实现了ITestListener接口。下面是重载TestListenerAdapter类的代码
package main.java.com.dbyl.library.utils; /**
* Created by wwh on 17/2/17.
*/
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter; /**
*
* @author
*
*/
public class CustomTestngListener extends TestListenerAdapter {
Log log = new Log(this.getClass()); @Override
public void onTestSuccess(ITestResult tr) {
log.info("Test Success");
super.onTestSuccess(tr);
} @Override
public void onTestFailure(ITestResult tr) {
log.error("One Test Failure");
super.onTestFailure(tr);
takeScreenShot(tr);
} private void takeScreenShot(ITestResult tr) {
UITest b = (UITest) tr.getInstance();//ITestResult类型可以返回当前测试类的一个实例
b.takeScreenShot();//借助这个实例,调用其截图方法 } @Override
public void onTestSkipped(ITestResult tr) {
log.error("Test Skipped");
super.onTestSkipped(tr);
} @Override
public void onTestStart(ITestResult result) {
log.info("One Test Start");
super.onTestStart(result);
} @Override
public void onStart(ITestContext testContext) {
log.info("Before Any Test Start");
super.onStart(testContext);
} @Override
public void onFinish(ITestContext testContext) {
log.info("After All Tests Finish");
super.onFinish(testContext);
} }
简单总结
要想实现自动截图,需要做到三点:
- 继承带有截图方法的父类;
- 调用父类的init方法更新driver;
- 实现ITestListener接口或者重载TestListenerAdapter,并启用自定义的监听类;
留下的问题
测试Android应用和iOS应用需要使用不同的driver,进而需要定义两个测试类的父类。能不能只定义一个父类呢?
使用appium和testng实现Android自动截图的更多相关文章
- 执行testng appium用例失败,自动截图
新建一个截图监听类ScreenShotListener ,重写onTestFailure方法,里面定义了 监听的driver ,截图文件路径和名称 package com.fsssc.htsgl.ut ...
- testng 失败自动截图
testng执行case failed ,testng Listener会捕获执行失败,如果要实现失败自动截图,需要重写Listener的onTestFailure方法 那么首先新建一个Listene ...
- selenium 利用testNG对异常进行自动截图
哈哈哈,很久没写博客了,懒了. 因为一些原因最近需要把监听事件重新整理一下,开始没细想,直接copy网上的,其实结果发现报错很多,或者是达不到效果,然后把之前的代码翻出来,仔细看了一下.下面给一些需要 ...
- TestNG监听器实现用例运行失败自动截图、重运行功能
注: 以下内容引自 http://blog.csdn.net/sunnyyou2011/article/details/45894089 (此非原出处,亦为转载,但博主未注明原出处) 使用Testng ...
- 如何搭建基于C#和 Appium 的 Android自动测试环境
本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 如果想做手机端的自动化测试,Appium是首选的测试框架,因为网上使 ...
- Webdriver+Testng实现测试用例失败自动截图功能
testng执行测试用例的时候,如果用例执行失败会自动截图,方便后续排查问题 1.首先定义一个截图类: package com.rrx.utils; import java.io.File;impor ...
- selenium遇到异常自动截图
最近要在框架中添加case失败时,要自动截图,主要又两种方式,思想都是在抛异常的时候,捕获到异常,并作页面截图处理.今天坐下总结. 一.第一种方式,重写onException方法 只针对webdriv ...
- appium+Java+testng自动化框架搭建-第一季
app自动化越来越火,随着移动app的不断发展,手机端测试日益火爆,想成为一个高级软件测试工程师必须要掌握,那么我们今天就来搭建appium+Java+testng自动化测试框架. Appium环境搭 ...
- Android 自动取色并设置沉浸式状态栏
Android 自动取色并设置沉浸式状态栏 - Stars-One的杂货小窝 最近在进行产品的优化,也是研究了下沉浸式状态栏的实现方法及自动取色,记录一下笔记 设置沉浸式状态栏 1.添加依赖 这里,是 ...
随机推荐
- [转] makeFile文件作用
源文件地址 makefile关系到了整个工程的编译规则.一个工程中的源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后 ...
- ArcGIS 10.2 二次开发,兼容Visual Studio 2012二次开发,完美安装教程
GIS 经常安装是常有的事,每次重装系统都要浪费大半天去安装这个.所以凑这一次安装,把这个软件重新安装的步骤整理了一下,希望对大家有所帮助.这次整理的内容的关键优点是,对常见的出错内容进行了归纳整理. ...
- td中内容自动换行
使用<table> 进行页面开发,会遇到字符串很长将table撑开变形的问题,在网上搜了一些,终于找到 一个比较好用的解决方法.贴出来,方便以后使用.在table标签中加入如下的style ...
- Intellij IDEA 拷贝的项目变为红色名字
Intellij IDEA 拷贝的项目变为红色名字 学习了:https://blog.csdn.net/lishaoran369/article/details/72991805 settings & ...
- Solidworks如何改变零件颜色
如图所示装配体有三个零件,现在我想把移动件的颜色变成红色 鼠标左键单击要改变颜色的零件(这里点击"移动件"),然后在弹出的菜单中选择颜色,最后点击"编辑颜色" ...
- C 语言实例
C 语言实例 C 语言实例 - 输出 "Hello, World!" C 语言实例 - 输出整数 C 语言实例 - 两个数字相加 C 语言实例 - 两个浮点数相乘 C 语言实例 - ...
- CocoaAsyncSocket 文档1:Socket简单介绍
前言 CocoaAsyncSocket是 IOS下广泛应用的Socket三方库,网上相关样例数不胜数.这里我就不直接上代码,本文由B9班的真高兴发表于CSDN博客.另辟一条思路:翻译SocketAsy ...
- 高阶函数:sorted
排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的 ...
- 【Linux】线程并发拷贝程序
据说大连某211高校的李教授越来越重口.不仅延续要求他所带的每个本科班.都要写一份线程并发拷贝程序的传统,并且还開始规定不能用Java语言写作.导致我之前写的<[Java]线程并发拷贝程序> ...
- jquery元素分组插件,用于把一连串元素分成多组,如把多个a标签分成多组放入<li>元素中,可以用于简化多图滚动为一个元素滚动,兼容ie6
三个参数 <script type="text/javascript"> /* *sclass:设置包裹元素的类 * packages:设置包裹的元素 * row:设置 ...