原文地址https://blog.csdn.net/iamhuanggua/article/details/53104345

简介

 

一直以来,安卓UI自动化测试都存在以下两个障碍,一是测试工具Mokey/Appium等的学习成本较高,不方便刚接触移动端自动化的新手入门;另一个是,在测试代码书写中耗费在控件元素查找上的时间太多,在一些稍微复杂的应用中尤其突出。LazyAndroid正是为了解决这些问题而诞生的一款UI自动化测试框架。它基于appium,封装了appiumDriver的设置、安卓基本控件的使用和手机的滑动、按键等基本操作,增加了元素查找的重试机制、异常处理截屏等。结合LazyUiautomaterViewer工具自动生成的bean层java代码,更可以使QA可以无需亲自动手完成具体页面中控件的抓取,无需关心appium api的使用,即可轻松完成测试逻辑代码的书写。

使用方法

一.下载源码进行编译,将源码编译生成的jar包推送到目标maven 私服仓库或者直接将jar包导入到测试项目中。源码下载地址: http://github.com/lazytestteam/LazyAndroid

二.建立测试工程,引入上面的jar包,开始测试代码的书写。下面以测试京东钱包apk的登陆和转账功能为例,以Maven作为项目管理工具,结合LazyUiAutomaterViewer工具进行示范(LazyAndroid也可以不依赖LazyUiAutomaterViewer单独使用)。

建立maven测试工程(前提是已下载安装maven和IDE的maven插件),在pom文件中添加jar包依赖(jar包已推到我们公司maven私服)。

Pom文件如下:

<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>LazyAndroidTestDemo</groupId>

<artifactId>LazyAndroidTestDemo</artifactId>

<version>0.0.1-SNAPSHOT</version>

<build>

<sourceDirectory>src</sourceDirectory>

<plugins>

<plugin>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.1</version>

<configuration>

<source>1.7</source>

<target>1.7</target>

</configuration>

</plugin>

</plugins>

</build>

<dependencies>

<dependency>

<groupId>org.testng</groupId>

<artifactId>testng</artifactId>

<version>6.9.9</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-log4j12</artifactId>

<version>1.7.2</version>

</dependency>

                  <dependency>

                                <groupId>lazyAndroid</groupId>

                                <artifactId>lazyAndroid</artifactId>

                                <version>0.0.1-SNAPSHOT</version>

                  </dependency>

</dependencies>

</project>

三.抓取页面元素导出java文件。

手机使用USB线连上电脑,启动LazyUiAutomaterViewer,进行截屏和抓取。LazyUiAutomaterViewer工具的获取及使用方法参见《LazyUiAutomatorViewer使用说明》

四.开始测试代码的书写:

  • 导入Bean层代码。将LazyUiAutomaterViewer自动生成的java代码导入到项目bean层中。

下面是京东钱包登录页使用LazyUiAutomaterViewer自动抓取、导出的java文件:

package test.java.bean;

import lazy.android.annotations.*;

import lazy.android.bean.BaseBean;

import lazy.android.controls.*;

import io.appium.java_client.AppiumDriver;

/**

* Gennerated by lazyUiautomaterViewer.

*/

public classLoginBean extendsBaseBean{

@Xpath(xpath={"//android.widget.TextView[@resource-id='com.wangyin.payment:id/txt_main_title']"})

@Description(description="登录")

public  PlainText textView1;

@Xpath(xpath={"//android.view.View[@resource-id='com.wangyin.payment:id/view_divider_line']"})

@Description(description="")

public  View view1;

@Xpath(xpath={"//android.widget.ScrollView[@resource-id='com.wangyin.payment:id/fragment_container']"})

@Description(description="")

public  View scrollView2;

@Xpath(xpath={"//android.widget.RadioGroup[@resource-id='com.wangyin.payment:id/main_footbar_menu']"})

@Description(description="")

public  View radioGroup3;

@Xpath(xpath={"//android.widget.RadioButton[@resource-id='com.wangyin.payment:id/login_tab_phone']"})

@Description(description="钱包账户")

public  Click jdpayAccount;

@Xpath(xpath={"//android.widget.RadioButton[@resource-id='com.wangyin.payment:id/login_tab_jd']"})

@Description(description="京东账户")

public  Click jdAccount;

@Xpath(xpath={"//android.widget.LinearLayout[@resource-id='com.wangyin.payment:id/layout_login_jd']/android.view.View[1]"})

@Description(description="")

public  View view4;

@Xpath(xpath={"//android.widget.EditText[@resource-id='com.wangyin.payment:id/cp_input_combox_jd']"})

@Description(description="京东商城手机号/用户名/邮箱")

public  Text editTextUserName;

@Xpath(xpath={"//android.widget.TextView[@text='账号']"})

@Description(description="账号")

public  PlainText textView2;

@Xpath(xpath={"//android.widget.ImageView"})

@Description(description="")

public  View imageView5;

@Xpath(xpath={"//android.widget.EditText[@resource-id='com.wangyin.payment:id/cp_input_pwd']"})

@Description(description="")

public  Text editJDTextPwd;

@Xpath(xpath={"//android.widget.TextView[@text='密码']"})

@Description(description="密码")

public  PlainText textView3;

@Xpath(xpath={"//android.widget.LinearLayout[@resource-id='com.wangyin.payment:id/layout_login_jd']/android.view.View[2]"})

@Description(description="")

public  View view6;

@Xpath(xpath={"//android.widget.Button[@resource-id='com.wangyin.payment:id/btn_login_jd']"})

@Description(description="登录")

public  Click buttonLogin;

@Xpath(xpath={"//android.widget.TextView[@resource-id='com.wangyin.payment:id/txt_jd_register']"})

@Description(description="注册京东账户")

public  PlainText textView4;

@Xpath(xpath={"//android.widget.TextView[@resource-id='com.wangyin.payment:id/txt_forget_pwd']"})

@Description(description="忘记密码?")

public  PlainText textView5;

@Xpath(xpath={"//android.widget.EditText[@resource-id='com.wangyin.payment:id/cp_input_combox_wy']"})

@Description(description="请填写手机号")

public  Text editTextPhone;

@Xpath(xpath={"//android.widget.TextView[@text='手机号']"})

@Description(description="手机号")

public  PlainText textViewPhone;

@Xpath(xpath={"//android.widget.Button[@resource-id='com.wangyin.payment:id/btn_login']"})

@Description(description="下一步")

public  Click nextStep;

@Xpath(xpath={"//android.widget.EditText[@resource-id='com.wangyin.payment:id/cp_input_pwd']"})

@Description(description="")

public  Text editjdPayTextPwd;

@Xpath(xpath={"//android.widget.TextView[@text='密码']"})

@Description(description="密码")

public  PlainText textViewPwd;

@Xpath(xpath={"//android.widget.Button[@resource-id='com.wangyin.payment:id/btn_login']"})

@Description(description="登录")

public  Click jdpayLogin;

publicLoginBean(AppiumDriveraDriver){super(aDriver);}

}

  • page层代码编写。根据测试逻辑,完成page层代码的书写。基于bean层定义的控件变量,完成基本操作。

package test.java.page;

importorg.openqa.selenium.WebElement;

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

import test.java.bean.LifeBean;

import test.java.bean.LifeBean2;

importtest.java.bean.LoginBean;

importtest.java.bean.MineBean;

importtest.java.bean.TodayBean;

importio.appium.java_client.AppiumDriver;

importlazy.android.common.LazyDriver;

public class DemoPage {

private Loggerlogger = LoggerFactory.getLogger(this.getClass());

private LazyDriverlazyDriver;

private AppiumDriverdriver;

private TodayBeantodayBean;

private LifeBean2lifeBean2;

private MineBeanmineBean;

private LoginBeanloginBean;

/**

* 构造函数

* @param aLazyDriver

*/

public DemoPage(LazyDriveraLazyDriver) {

lazyDriver = aLazyDriver;

driver = lazyDriver.getDriver();

todayBean = new TodayBean(driver);

new LifeBean(driver);

lifeBean2 = new LifeBean2(driver);

mineBean = new MineBean(driver);

loginBean = new LoginBean(driver);

}

/**

* 登陆操作

*/

public void login() {

logger.info("login by jdpay account!");

todayBean.textViewToday.expectElementExistOrNot(true);

todayBean.textViewMine.expectElementExistOrNot(true);

todayBean.textViewMine.click();

lazyDriver.handleFailure("screen test:");

mineBean.login.expectElementExistOrNot(true);

mineBean.login.click();

loginBean.jdpayAccount.expectElementExistOrNot(true);

loginBean.jdpayAccount.click();

loginBean.editTextPhone.input("13034631475");

loginBean.nextStep.click();

loginBean.editjdPayTextPwd.expectElementExistOrNot(true);

loginBean.editjdPayTextPwd.input("haha123");

loginBean.jdpayLogin.click();

lazyDriver.swipeToLeft();

}

/**

* 转账操作

* @throws InterruptedException

*/

public void doTranAccount() throws InterruptedException {

logger.info("transfer accounts!");

todayBean.textViewLife.click();

lazyDriver.swipeDown();

lazyDriver.swipeToLeft();

lifeBean2.textViewTransAccount.click();

WebElement wl = lazyDriver.findElementByText("转账给朋友");

wl.click();

Thread.sleep(1000);

lazyDriver.goBack();

lazyDriver.goBack();

}

}

其中,需要注意一下构造函数。在Page层的构造函数中,需要做两个事情。一个是给LazyDriver赋值(通过Test层传递过来的LazyDriver对象),另一个是通过LazyDriver对象获取appiumDriver,来构造Bean层的类。Page层用到的所有bean层类都需要传入appiumDriver进行构造,见下图:

  • 调用page层方法,完成测试。

package test.java.test;

importjava.net.MalformedURLException;

importorg.testng.annotations.BeforeClass;

importorg.testng.annotations.Test;

importtest.java.page.DemoPage;

importlazy.android.common.LazyDriver;

public class DemoTest {

private DemoPagedemoPage;

@BeforeClass

public void init() throws MalformedURLException {

LazyDriver lazyDriver =new LazyDriver("jdpay.apk","com.wangyin.payment",".home.ui.MainActivity","4.2.2",false);

demoPage = new DemoPage(lazyDriver);

}

/**

* 登陆测试

*/

@Test

public void loginTest() {

demoPage.login();

}

/**

* 转账测试

* @throws InterruptedException

*/

@Test

public void tranAccount() throws InterruptedException {

demoPage.doTranAccount();

}

}

在test层代码的BeforeClass(这个demo使用了testng,但是不是必须的)中,构造了一个lazyDriver,然后通过它去构造page层的类。

和如下appiumDriver的繁琐设置相比较,是不是简化很多了?

Bean、Page和Test层是我们在测试代码编写过程中,为了区分代码层次,根据代码功能定义的三个包名,不是必须的,大家可以灵活处理。

五.启动appium, 运行或调试测试代码,执行测试。

Demo工程源码:https://github.com/lazytestteam/LazyAndroidDemo

详细的使用说明请参考http://blog.csdn.net/kaka1121/article/details/53301517

自动化测试中级篇——LazyAndroid UI自动化测试框架使用指南的更多相关文章

  1. 自动化测试 接口自动化及UI自动化测试平台设计演示

    接口自动化及UI自动化测试平台设计演示   by:授客  QQ:1033553122 欢迎加入全国软件测试交流qq群:7156436 大家好,我是授客. 本视频意在分享个人,基于Python,Djan ...

  2. ui自动化测试的意义与理解

    分层测试的思想 分层测试(有的也叫测试金字塔)是最近几年慢慢流行.火热起来的,也逐渐得到了大家的认可,大家应该已经比较熟悉分层测试的思想了,不太了解的可以自行找一些相应的渠道去补充一下上下文的知识. ...

  3. [原创]浅谈Web UI自动化测试

    [原创]浅谈Web UI自动化测试 Web UI自动化测试相信大家都不陌生,今天来谈谈这个,我最早接触自动化测试时大约是在2004年,2006年当时在腾讯财付通算是开始正式接触自动化测试,之所以是正式 ...

  4. 【转】 UI自动化测试的关注点

    我发现了,大家极度关心自动化测试,尤其是UI自动化测试,虽然现在作为专项测试,离开这些越来越远了,但总能遥想以前,我总能想起自己做nokia的WindowsLive的ui自动化,做web的自动化测试, ...

  5. 数据驱动 vs 关键字驱动:对搭建UI自动化测试框架的探索

    UI自动化测试用例剖析 让我们先从分析一端自动化测试案例的代码开始我们的旅程.以下是我之前写的一个自动化测试的小Demo.这个Demo基于Selenium与Java.由于现在Selenium在自动化测 ...

  6. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  7. UI自动化测试框架(项目实战)python、Selenium(日志、邮件、pageobject)

    其实百度UI自动化测试框架,会出来很多相关的信息,不过就没有找到纯项目的,无法拿来使用的:所以我最近就写了一个简单,不过可以拿来在真正项目中可以使用的测试框架. 项目的地址:https://githu ...

  8. APP的UI自动化测试框架及平台化探索

    顾铮,10年+测试及测试开发相关经验,2014年加入京东,曾主导设计开发UI测试框架,参与CI测试平台建设,现负责iOS侧的工具,框架建设.在UI自动化,性能测试,单元测试方面有较深入研究,在App, ...

  9. 简单Web UI 自动化测试框架 pyse

    WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动 ...

随机推荐

  1. linux中nmcli命令详解

    https://www.iyunv.com/thread-269695-1-1.html http://www.178linux.com/44668

  2. Cesium - 离线使用方法

    使用Cesium可以直观的看基于DEM切片产生的Terrain地形数据,有种身临其境的感觉,但缺点是Cesium默认缺省加载了微软Bing提供的地形以及遥感影像数据,可以跟踪日志,总提示让你申请微软的 ...

  3. Kafka中Producer端封装自定义消息

    我们知道KeywordMessage就是被kafka发送和存储的对象.所以只需要模拟出这个就可以发送自定义消息了. 比如我需要将用户的id,user,age,address和访问ip和访问date记录 ...

  4. [转载]会引起全表扫描的几种SQL

    查询语句的时候尽量避免全表扫描,使用全扫描,索引扫描!会引起全表扫描的几种SQL如下 1.模糊查询效率很低: 原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like ‘%... ...

  5. 解决Qt程序在Linux下无法输入中文的办法(与下文连接)

    在安装QT集成开发工具包之前需要先安装build-essential和libncurses5-dev这两个开发工具和库,libncurses5-dev库是一个在Linux/Unix下广泛应用的图形函数 ...

  6. iOS富文本组件的实现—DTCoreText源码解析 数据篇

    本文转载 http://blog.cnbang.net/tech/2630/ DTCoreText是个开源的iOS富文本组件,它可以解析HTML与CSS最终用CoreText绘制出来,通常用于在一些需 ...

  7. 图解利用vmware工具进行虚拟机克隆

    在vmware上创建一台完整的虚拟机,在该创建的虚拟机上进行克隆,先关闭创建的虚拟机,然后选中你要克隆的虚拟机,右击->管理->克隆,然后点击下一步,如下图所示: 2 然后点击下一步,如下 ...

  8. 【Java nio】 Blocking nio

    package com.slp.nio; import org.junit.Test; import java.io.File; import java.io.IOException; import ...

  9. 10.Node.js核心模块

    1.全局对象2.常用工具3.事件机制4.文件系统访问5.HTTP服务与客户端 一.全局对象(Global Object), 与window对象一样 process ==> 全局变量, 描述当前N ...

  10. 【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)

    [BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M ...