ui自动化( 五 )
ui自动化测试 之页面对象设计模式
在前面已经很系统的学习了UI自动化测试的技术栈的知识体系,但是在维护的成本而言还需要考虑进一步的优化,就可以使用页面对象设计模式,它的优势具体可以总结为如下:
- 创建可以跨多个测试用例共享的代码
- 减少重复代码的数量
- 如果用户界面发生了维护,我们只需要维护一个地方,这样修改以及维护的成本相对而言是比较低的
一、目录结构设计
下面具体针对这部分的目录进行设计,具体的目录结构为:

下面是详细的解释下每个目录的是干什么的,具体总结为如下:
-
base的包下主要编写基础的代码,可以理解为基础层
-
page包下主要存放对象层的代码,可以理解为对象层
-
test报下主要存放编写的测试模块的代码,可以理解为测试层
-
utils下存放的主要是工具类的代码,比如针对JSON文件,YAML文件的处理
-
common下主要存放的是公共类的代码,比如文件目录的处理
-
data主要存放测试过程中使用到的数据
-
report主要存储的是测试报告这部分
二、页面对象设计模式
上面已经很详细的解释了页面对象设计模式它的优势,以及目录结构的设计,下面依次来实现各个部分的代码。
2.1、基础层
下面主要实现基础层的代码,在base包下创建模块为base.py的文件,里面的源码信息为:
from selenium import webdriver
from selenium.webdriver.support.expected_conditions import NoSuchElementException
from selenium.webdriver.common.by import By
import time as t
class WebDriver(object):
def __init__(self,driver):
# self.driver=webdriver.Chrome()
self.driver=driver
def findElement(self,*loc):
'''单个元素的定位方式'''
try:
return self.driver.find_element(*loc)
except NoSuchElementException as e:
return e.args[0]
def findElements(self,*loc):
'''多个元素的定位方式'''
try:
return self.driver.find_elements(*loc)
except NoSuchElementException as e:
return e.args[0]
2.2、对象层
下面以sina的邮箱为案例来编写具体的代码,在page包下创建login.py的文件,里面的源码具体为:
from selenium import webdriver
from selenium.webdriver.support.expected_conditions import NoSuchElementException
from selenium.webdriver.common.by import By
import time as t
from base.base import WebDriver
class Login(WebDriver):
username=(By.ID,'freename')
password=(By.ID,'freepassword')
loginButton=(By.LINK_TEXT,'登录')
userDiv=(By.XPATH,'/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
passwdDiv=(By.XPATH,'/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[2]')
emailDiv=(By.XPATH,'//*[@id="user_id"]/em[2]')
islogin=(By.ID,'store1')
def inputUsername(self,username):
t.sleep(3)
self.findElement(*self.username).send_keys(username)
def inputPassword(self,password):
t.sleep(3)
self.findElement(*self.password).send_keys(password)
def clickLogin(self):
t.sleep(3)
self.findElement(*self.loginButton).click()
def getUserDiv(self):
'''获取账户的错误信息'''
t.sleep(4)
return self.findElement(*self.userDiv).text
def getPasswdDiv(self):
'''获取密码的错误信息'''
t.sleep(3)
return self.findElement(*self.passwdDiv).text
def getEmailDiv(self):
'''登录成功'''
t.sleep(3)
return self.findElement(*self.emailDiv).text
def autoLogin(self):
'''是否勾选自动登录'''
t.sleep(3)
return self.findElement(*self.islogin).is_selected()
def clickAutologin(self):
'''取消勾选自动登录'''
t.sleep(3)
return self.findElement(*self.islogin).click()
def login(self,username,password):
self.inputUsername(username=username)
self.inputPassword(password=password)
self.clickLogin()
2.3、测试层
下面在测试层,也就是test包下创建test_login.py的模块,原代码具体为:
from selenium import webdriver
from selenium.webdriver.support.expected_conditions import NoSuchElementException
from selenium.webdriver.common.by import By
import time as t
from page.login import Login
import unittest
from utils.operationjson import readJson
class Testlogin(unittest.TestCase, Login):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('https://mail.sina.com.cn/#')
self.driver.implicitly_wait(20)
def tearDown(self) -> None:
self.driver.quit()
def test_username_null(self):
'''登录验证:账户为空错误信息'''
self.login(username='', password='')
self.assertEqual(self.getUserDiv(),readJson()['nullEmail'])
def test_password_format(self):
'''登录验证:验证邮箱格式'''
self.login(username='244566', password='546777')
self.assertEqual(self.getUserDiv(),readJson()['formatEmail'])
def test_username_password_error(self):
'''登录验证:登录名或密码错误'''
self.login(username='323@sina.com', password='546777')
self.assertEqual(self.getUserDiv(),readJson()['loginEmail'])
def test_password_null(self):
'''登录验证:密码为空的错误信息'''
self.login(username='323@sina.com', password='')
self.assertEqual(self.getPasswdDiv(),readJson()['nullPasswd'])
def test_email_success(self):
'''登录验证:登录成功'''
self.login(username='wuya1303@sina.com', password='admin123')
self.assertEqual(self.getEmailDiv(),'wuya1303@sina.com')
def test_auto_login(self):
'''登录验证:验证自动登录勾选'''
self.assertTrue(self.autoLogin())
def test_auto_login_camcel(self):
'''登录验证:验证自动登录勾选'''
self.clickAutologin()
self.assertFalse(self.autoLogin())
if __name__ == '__main__':
unittest.main()
2.4、公共方法
下面在common包下创建public.py的模块,里面主要编写针对文件路径的处理,具体源码如下:
mport os
def base_dir():
return os.path.dirname(os.path.dirname(__file__))
def filePath(directory,filename):
'''获取文件的详细路径
param directory 目录
param filename 文件名称
return'''
return os.path.join(base_dir(),directory,filename)
2.5、数据驱动
下面在data的文件夹下创建login.json的文件,把登录使用到的数据分离到sina.json的文件里面,该文件的具体内容为:
{
"nullEmail":"请输入邮箱名",
"formatEmail": "您输入的邮箱名格式不正确",
"loginEmail": "登录名或密码错误",
"nullPasswd": "请输入密码"
}
2.6、工具类
下面在具体的工具类中编写针对JSON文件的处理,创建的模块名称为:operationJson.py,具体源码为:
import json
from common.public import filePath
def readJson():
return json.load(open(filePath(
directory='data',
filename='login.json'),encoding='utf-8'))
print(readJson())
2.7、生成报告
在项目目录下创建一个模块用来生成测试报告,模块名为main。py 具体代码为:
import unittest
import os
import HTMLTestRunner
from common.public import *
import time
def allTests():
'''获取要执行的测试模块'''
suita=unittest.TestLoader().discover(
start_dir=os.path.join(base_dir(),'test'),
pattern='test_*.py')
return suita
def getNowTime():
return time.strftime('%y-%m-%d %H_%M_%S',time.localtime(time.time()))
def run():
filename=filePath(directory='report',filename=getNowTime()+'.html')
fp=open(filename,'wb')
runnner=HTMLTestRunner.HTMLTestRunner(
stream=fp,
title='Sina Email',
description='ui自动化测试报告'
)
runnner.run(allTests())
if __name__ == '__main__':
run()
运行程序,测试报告会生成在report文件下
最后项目的所有目录为:
最终生成的测试报告如下:


浙公网安备 33010602011771号