在我们学习Page Object Model之前,我们先了解一下Page Object Model(以下简称POM).

为什么要POM

用UiAutomator启动UI自动化测试不是一件困难的任务。你只需要查找元素,对元素操作就可以了。来看一个登录APP的简单的脚本。

 package com.gqou.testdemo;

 import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector; import org.junit.Test;
import org.junit.runner.RunWith; import static junit.framework.TestCase.assertEquals; /**
* Created by guangqian on 2016/4/22.
*/
@RunWith(AndroidJUnit4.class)
public class SimpleTest { @Test
public void 测试登录成功() throws Exception{
// 查找图标并点击启动app
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
uiDevice.findObject(new UiSelector().text("TestDemo")).clickAndWaitForNewWindow();
// 输入用户名,密码并点击Login
UiObject usernameObj = uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/name_txt"));
UiObject pwdObj = uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/pwd_txt"));
UiObject loginBtn = uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/login_btn"));
UiObject welcomeTip = uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/welcome_tip")); usernameObj.click();
usernameObj.setText("username");
pwdObj.click();
pwdObj.setText("password"); loginBtn.clickAndWaitForNewWindow(); // 校验登录成功信息
assertEquals("congratulations", welcomeTip.getText());
}
}
你可以看到,我们所做的就是查找元素并为那些元素填值,点击等操作。
这是一个比较简单的脚本,脚本维护看起来也很容易。但是随着时间增长,你会编写更多的脚本代码,维护也会变得越来越困难。
脚本维护的主要面临的问题就是:比如有10份脚本使用同一个界面元素,一旦界面元素发生了变化,你需要更改10份脚本。这不仅浪费时间而且还很容易出错。
本文介绍的脚本维护比较好的方法就是针对元素的查找,操作等操作来创建一个独立的类文件。这个类文件可以被使用那些元素的所有脚本重用。将来如果界面元素发生变化,只需要修改一份类文件就可以了,不需要再去修改10份脚本文件。
这个方法就叫做Page Object Model。它可以让我们的代码更加易于阅读,维护和重用。
   

什么是POM

1. Page Object Model是一种设计模式,为界面对象创建一个对象库
2. 在这个模式下,应用的每一个界面都应该有一个相应的界面类
3. 界面类会查找界面的元素也包含对元素操作的方法
4. 方法的命名应该根据它的行为来命名,例如:如果程序等待支付网关出现在界面上,方法应该被命名类似waitForPaymentScreenDisplay().
 

POM的优点

1. POM意味着对界面上的元素的操作从原来的测试用例代码中分离出来,这样使我们的代码清晰并且易于理解。
2. 第二个好处是对象库是独立的。因此我们可以通过不同的工具使用相同的对象库来达到不同的目的。比如:我们可以集成TestNG/JUnit来做功能测试,同时也可以使用JBehave/Cucumber做验收测试。
3. 由于方法的可重用,我们的代码会变得更少,有效性更高。
4. 方法能真实的映射出用户在界面上的操作行为,比如:点击过按钮之后并跳到主界面,方法名就会类似"gotoHomePage".
 

怎么实现POM

POM的基本结构是应用的所有元素和元素的操作方法都被封装在一个类文件中,测试用例代码只需要调用这个类文件中的方法即可。
 

完整的例子:

 
第一步:打开应用app
第二步:输入用户名,密码,点击Login
第三步: 验证登录成功
 
有两个界面:登录界面,欢迎界面,所以我们要创建两个界面的类文件LoginActivity,WelcomeActivity
 

LoginActivity.java

 package com.gqou.testdemo.pages;

 import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector; /**
* Created by guangqian on 2016/4/22.
*/
public class LoginActivity { UiDevice uiDevice;
UiObject mUserName;
UiObject mPasswd;
UiObject mLogin; public LoginActivity(UiDevice uiDevice){
this.uiDevice = uiDevice;
mUserName = this.uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/name_txt"));
mPasswd = this.uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/pwd_txt"));
mLogin = this.uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/login_btn"));
} /**
* 输入用户名
* @param userName
* @throws Exception
*/
private void setmUserName(String userName) throws Exception{
mUserName.click();
mUserName.setText(userName);
} /**
* 输入密码
* @param pwd
* @throws Exception
*/
private void setmPasswd(String pwd) throws Exception{
mPasswd.click();
mPasswd.setText(pwd);
} /**
* 点击登录按钮
* @throws Exception
*/
private void clickLogin()throws Exception{
mLogin.clickAndWaitForNewWindow();
} /**
* 封装登录App操作
* @param username
* @param pwd
* @throws Exception
*/
public void loginApp(String username, String pwd) throws Exception{
this.setmUserName(username);
this.setmPasswd(pwd);
this.clickLogin();
}
}

WelcomeActivity.java

 package com.gqou.testdemo.pages;

 import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiSelector; /**
* Created by guangqian on 2016/4/22.
*/
public class WelcomeActivity {
UiDevice uiDevice;
UiObject welcomeTip; public WelcomeActivity(UiDevice uiDevice){
this.uiDevice = uiDevice;
welcomeTip = this.uiDevice.findObject(new UiSelector().resourceId("com.gqou.testdemo:id/welcome_tip"));
} /**
* 获取欢迎提示语内容
* @return
* @throws Exception
*/
public String getWelcomeTip() throws Exception{
return welcomeTip.getText();
} }

POMForLoginTest.java

 package com.gqou.testdemo.testcases;

 import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiSelector; import com.gqou.testdemo.pages.LoginActivity;
import com.gqou.testdemo.pages.WelcomeActivity; import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith; import static junit.framework.TestCase.assertEquals;
/**
* Created by guangqian on 2016/4/22.
*/
@RunWith(AndroidJUnit4.class)
public class POMForLoginTest { public static UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
private static LoginActivity objLogin;
private static WelcomeActivity objWelcome; @Before
public void setUp() throws Exception {
// 打开应用
uiDevice.findObject(new UiSelector().text("TestDemo")).clickAndWaitForNewWindow();
// 创建界面实例对象
objLogin = new LoginActivity(uiDevice);
objWelcome = new WelcomeActivity(uiDevice); } @Test
public void 测试App登录成功() throws Exception {
// 登录app
objLogin.loginApp("Tom", "123456");
// 获取主界面提示语
String tips = objWelcome.getWelcomeTip();
// 判断提示语是否为预期
assertEquals("congratulations", tips);
}
}

Good Luck!

水平有限,欢迎各位大牛点评,多谢支持!

 
 
 

Page Object 模式编写UiAutomator脚本的更多相关文章

  1. 转 Page Object模式

    Page Object模式是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通 ...

  2. UI自动化测试的Page Object模式

    在UI级的自动化测试框架中,当页面样式改变或者页面元素属性改变,那么代码也要随之进行修改,如何做到高效快速的修改代码来适应这些改变呢,这个时候可以引入Page Object模式,也是页面对象设计模式. ...

  3. 【C#|.NET】从细节出发(三) 逻辑层事务和page object模式

    一. 业务逻辑层的事务问题 如果你的程序分层清晰并且系统禁用复杂存储过程,那么在DA中的职责比较单一.程序的逻辑通过BLL调用各种不同模块的DA来实现数据操作.如果当需要不同模块在一个事务的时候,问题 ...

  4. selenium page object模式

    页面对象模式将测试代码和被测试页面的元素及操作进行分离,以降低页面元素的变化对测试代码的影响.每个被测试的页面都会被定义一个类,类中会定位元素和操作. 如果不使用page object模式,则相同的操 ...

  5. 浅析selenium的page object模式

    selenium目前比较流行的设计模式就是page object,那么到底什么是page object呢,简单来说,就是把页面作为对象,在使用中传递页面对象,来使用页面对象中相应的成员或者方法,能更好 ...

  6. python+selenium自动化软件测试(第7章):Page Object模式

    什么是Page ObjectModel模式Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页 ...

  7. 使用page object模式抓取几个主要城市的pm2.5并从小到大排序后写入txt文档

    #coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...

  8. python selenium-8 Page Object模式

    封装空间操作为一个接口使用,而不是直接在页面中查找 from selenium import webdriver from selenium.webdriver.common.by import By ...

  9. web自动化中的page object模式

    一. 原理 将页面的元素定位和元素行为封装成一个page类,实现页面对象和测试用例分离 类的属性:元素定位 类的行为:元素的操作 测试用例:调用所需页面对象中的行为,组成测试用例 二. 好处 1. 当 ...

随机推荐

  1. zoj1873 Let it Bead

    思路:polya裸题,如果是旋转,对于旋转i格的循环节长度len=lcm(i,n)/i,个数就是n/len=gcd(i,n):如果是翻转,奇数个点对称轴就是一个点一条边,那么循环节个数即n/2+1, ...

  2. 绑定本地Service并与之通信

    绑定Service需要调用 public boolean bindService (Intent service, ServiceConnection conn, int flags): 传入一个Se ...

  3. (转) oc static extern 和const

    static 全局的,可以改的,如果在一个类中声明static,类中其他地方用到的时候,也是使用的改变量.和java类似,但不能用类名直接访问. const 是常量,不可以改的 extern 1.假如 ...

  4. 关于ubuntu上执行错误命令报错

    Sorry, command-not-found has crashed! 新安装了一台ubuntu server 安装时用中文安装的,之后命令行下各种乱码,最后也不知道是修改哪里造成的 每次执行一次 ...

  5. sed工具使用

    sed命令使用形式 1.sed命令从管道中读取数据处理 command | sed ' edit command' 通过管道把一个命令的标准输出读入到sed的标准输入,sed就起到了过滤作用 2.se ...

  6. node-mongodb-native的几种连接数据库的方式

    h1,h2,h3,h4,h5,h6,p,blockquote { margin: 0; padding: 0;}body { font-family: "Helvetica Neue&quo ...

  7. Boolean 布尔类型详解

    这是最简单的类型.boolean 表达了真值,可以为 TRUE 或 FALSE.两个都不区分大小写. 要明确地将一个值转换成 boolean,用 (bool)或者 (boolean) 来强制转换.但是 ...

  8. JS获取IP、MAC和主机名的五种方法

    javascript获取客户端IP的小程序,下面的代码是我在所有windowsNT5.0及以上的系统上都测试通过的,喜欢的朋友可以收藏下.今天在搞JS(javascript)获取客户端IP的小程序,上 ...

  9. MAC 终端快捷建

    常用的快捷键: Ctrl + d        删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit:处理多行标准输入时也表示eof) Ctrl + h        退格删 ...

  10. python—cookielib模块对cookies的操作

    最近用python写爬虫爬了点数据,确实是很好用的东西,今天对python如何操作cookie进行一下总结. python内置有cookielib模块操作cookie,配合urllib模块就可以了很轻 ...