在我们学习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. IO流中的文件创建并且写入读取

    package com.java.inoutputstreamDmeo.www; import java.io.File;import java.io.FileInputStream;import j ...

  2. bzoj4330:JSOI2012 爱之项链

    题目大意:一串项链由n个戒指组成,对于每个戒指,一共有M个点,R种颜色,且旋转后相同的戒指是相同的,然后一串项链又由N个戒指组成,同时要满足相邻的两个戒指不能相同,这串项链上某个位置插入了一个特殊的东 ...

  3. nginx 代理 proxy_pass设置

    #img.test.com/img1 实际访问的路径是 http://127.0.0.1:123/a1 #img.test.com/img2 实际访问的路径是 http://127.0.0.1:123 ...

  4. js 中如何通过提示框跳转页面

    通过提示框跳转页面 <!doctype html> <html lang="en"> <head> <meta charset=" ...

  5. PHP下拉框选择的实现方法

    实现 第一种PHP下拉框实现方法: < ?php //提交下拉框; //直接饱触发onchange事件的结果 $id=$_GET['myselect']; // myselect 为locati ...

  6. 转载“用USBOOT制作DOS启动盘”

    使用软件: Usboot和MaxDOS_5.6s_U盘版. 由于我的U盘容量比较小,暂时只能做DOS启动功能,其它功能如Windows PE,等我以后测试成功后再补充说明. U盘是啥? 读音优盘,可以 ...

  7. 每天学点管理学知识——情绪ABC理论

    什么是ABC理论 ABC理论(ABC Theory of Emotion)是由美国心理学家埃利斯创建的.就是认为激发事件A(activating event 的第一个英文字母)只是引发情绪和行为后果C ...

  8. Js处理数据——前端分页工具

    这几天有小伙伴讨论起了分页的相关问题,这里我也简单讲下前端如何简单便捷的利用Js(库)写出优雅,好用的分页工具. 分页是个很简单又超多接触的技术点,粗略来讲分如下两种: 真分页--每次根据页码.页大小 ...

  9. App页面显示优化

    在开发移动端APP页面时,对各操作系统各种型号的手机进行适配是必须的.然鹅,上周在开发完一个落地页后,被测试给打了回来,其中列出了一个在我看来很小的问题:单击进入页面的时候,页面还没加载完的时候字体显 ...

  10. combo下拉列表选择

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...