一.Page Object设计模式
在测试自动化领域,针对界面做自动化测试最大挑战就是界面修改时,测试脚本也必须要做对应的修改,因此如何降低脚本的工作量,尽量减少修改的范围或者更有效率的管理界面的修改。Page Object Model的应用就是将网页界面元素与自动化测试逻辑分离。
1.为什么用Page Object Model
传统的自动化方法最常见的问题是随着测试套件的增长,测试的脚本维护变得越来越困难。其中维护成本最高的就是定位器的维护,导致定位器维护痛苦的原因有两个:一个是界面变化频繁,另外一个是测试脚本设计问题导致开发测试用例脚本代码中产生大量重复代码。一旦业务逻辑或者界面发生改变,测试人员就需要查看所有的源代码重新改写定位器;这些都使测试代码效率极其低下。
Page Object是解决上述问题的设计模式,利用Page Object设计模式只要用很少的代码就可以维护测试用例。
2.什么是Page Object Model
Page Object Model页面对象模型 是Selenium中广泛使用的设计模式,用于提高测试脚本维护工作量和减少测试代码重复。其实设计模式就是代码的架构,页面对象模型(POM)可用于任何类型的框架,如模块化,数据驱动,关键字驱动,混合框架等。一个页面就是一个面向对象的类,作为应用程序测试的页面(AUT)的接口。
3.Page Object Model的优点
开发频繁改动的时候,设计模式的优势就出来了,比如开发改了元素的ID,那么只要修改相应ID就行,所有和这个元素直接关联的定位器就都修改了,而原来的方式需要修改代码,涉及到的地方可能会有很多,改动起来很麻烦。
- 代码可重用性:通过编写代码一次来实现代码的可重用性,并将其用于不同的测试。
- 代码可维护性 :测试类代码和页面类代码(如定位器)分离,这使维护代码变得非常容易。UI发生更改时,仅在页面类代码中更改。这么做减少了大量重复测试代码
- 对象库 : 每个页面将被定义为一个类。页面中所有元素被作为类成员在类中定义。
- 可读性 :由于测试代码和UI操作分离,提高了代码可读性
二.Page Object Model实例
构建Page Object脚本步骤:
第一步,分析页面
为了达到学习效果,笔者实现一个登陆功能,包含两个页面,分别为登陆页面和欢迎页面,打开登陆页面,输入用户名密码,点击登陆按钮,会显示hello页面:
创建login.html文件,Html源码如下:
<html>
<head>
<meta charset="utf-8">
<title>登陆</title>
<style>
label {
display: block;
}
</style>
</head>
<body>
<form id="signup-form" action="hello.html">
<div>
<label class="username">用户名</label>
<input id="username" type="text" >
</div>
<div>
<label class="password">密码</label>
<input id="password" type="text">
</div>
<div>
<input id="signup" type="submit" value="登陆">
</div>
</form>
</body>
</html>
登陆页面有三个元素:
- 用户名文本框
- 密码文本框
- 登陆按钮
页面动作:
- 输入用户名
- 输入密码
- 点击登陆按钮
第二步:创建页面类来保存元素定位器及其方法。
下面创建LoginPage类:
from selenium import webdriver
from selenium.webdriver.common.by import By
class LoginPage():
username =("By.ID,'username'")
password =("By.ID,'password'")
login =("By.ID,'signup')
def __init__(self,driver):
self.driver=driver
def input_username(self,username):
self.driver.find_element(self.username).sendkeys(username)
def input_password(self,password):
self.driver.find_element(self.username).sendkeys(password)
def click_sign_up_button(self):
self.find_element(self.login).click()
return HelloPage(self.driver)
技术解释:LoginPage是登陆页有三个页面元素分别是用户名密码文本框和登陆按钮,所以LoginPage设计了三个属性,分别是三个页面元素的定位器。用户在登陆页面上的输入操作有用户名输入,密码输入,所以LoginPage有分别写了input_username和input_password方法;登陆页面有登陆操作也就是点击登陆按钮,所以LoginPage写了一个click_sign_up_button方法。页面中的各种操作方法相当于七巧板,具体想拼成什么样,根据需要自由组合。
创建Hello.html文件,Html源码如下:
<html>
<head>
<meta charset="utf-8">
<title>欢迎您到来</title>
</head>
<body>
<h1>谢谢!</h1>
<p>这是一个Page Object的例子</p>
</body>
</html>
欢迎页面没有任何元素和方法,只是为了显示登陆页面成功后的信息,下面创建HelloPage类:
class HelloPage():
pass
技术解释果页,这个页面是在登陆页面点击登陆按钮之后,跳转进入欢迎页面。
第三步,定义测试流程开发基础测试用例类
测试登陆功能,登陆包含输入用户名密码,点击按钮三个动作,实现测试类如下:
class SignUpFormTest():
def test_Login_page()
driver.get("login.html")
login =LoginPage(driver)
login.input_username('tester')
login.input_password('123456')
hello=login.click_sign_up_button()
return hello
上面是实现PageObject用页面的一个简单实例,下面是Page Object设计模式的最佳实践:
- 页面对象不应该有任何断言
- 页面对象应该表示页面的有意义的元素,而不一定是一个完整的页面
- 在浏览时,应该返回下一页的页面对象
通过使用Page Object设计模式,让测试脚本变得更加简洁和可读。元素定位器集中进行维护,降低了维护脚本的成本。用户界面的改变只影响页面对象而不影响测试脚本。Page Object是很不错的面向对象的设计。