po分层设计 全称:pageobject
一、po框架:页面对象的设计模式
二、优点:
1.元素、公共方法、用例都可以分离,进行分开管理
2.代码之间进行解耦
3.能提高代码的复用性和灵活性
三、缺点:代码量多,复杂性高
四、设计的过程
创建一系列相关的目录和python package包(文件夹),将相关的代码进行管理
如下:
总体的框架图:
先建一个cms项目,在项目下创建6个包:
(1)在创建一个cofing包==存放所有配置文件信息(比如项目路径和数据,用例的路径)可以封装路径
(2)在创建一个Data包放数据(测试数据)在Data包中创建一个Data目录(放测试数据)
测试环境的一些url地址和账号密码可以放在data中
(3)在创建一个repot包存放测试报告
在repot包中创建一个repot目录(存放报告)
(4)在创建一个public公共公开的包(存放一些功能用例)
子包一: 在public包中创建pages存放元素层流程层(封装所有页面的公共方法,基类)
子包二:在public包中创建utils包(处理公共类公共函数都存放在此)
可以在utils中来读取pages中封装的登录的流程(封装读取ini文件或者EXCEL表格的工具类和工具函数
(5)在创建一个TestCase用例包用来存放用例
编写测试用例
(6)在创建一个run包用来运行
通过运行测试用例中封装好的用例在运行然后在repot中生成测试报告
框架的思想:把整个用例进行拆分
==============================
第一个包:
config包:
代码:
congfing这个模块就是用来存放所有的目录的绝对路径
import os
#项目路径
project_path=os.path.dirname(os.path.dirname(file))
#config 包路径
config_path=os.path.join(project_path,“config”)
#data 包路径
data_path=os.path.join(project_path,“data”)
#report 包路径
report_path=os.path.join(project_path,“report”)
#public 包路径
public_path=os.path.join(project_path,“public”)
#public 包路径
run_path=os.path.join(project_path,“run”)
#testcase 包路径
testcase_path=os.path.join(project_path,“testcase”)
==============================
第二个包data包
存放数据
配置文件格式一般有:.ini、.conf、.xlsx、.xls、.cnf、.csv、.yaml
代码:
[uat_test]
wangzhi=http://cms.duoceshi.cn/cms/manage/login.do
zhanghao=admin
mima=123456
[uat_test02]
url=http://cms.duoceshi.cn/cms/manage/login.do
username=admin
pwd=123456
===========================
第三个包:public包
两个子包: basepage 包 utils包
basepage包:
这个模块主要是用来封装公共方法 比如:元素定位,控件,按钮等
from selenium import webdriver
from time import *
class basepage():
def setdriver(self,driver): #定义一个driver
self.driver=driver
def getdriver(self): #获取driver对象,保证页面都用同一一driver
return self.driver
#封装定位元素
def fin_elem(self,type,value):
if type == ‘id’: # id定位法
elem = self.driver.find_element_by_id(value)
elif type == 'name': # name定位法 elem = self.driver.find_element_by_name(value) elif type == 'class': # class定位法 elem = self.driver.find_element_by_class_name(value) elif type == 'xpath': # xpath定位法 elem = self.driver.find_element_by_xpath(value) elif type == 'css': # css定位法 elem = self.driver.find_element_by_css_selector(value) elif type == 'link': # link定位法 elem = self.driver.find_element_by_link_text(value) elif type == 'partial_link': # partial_link定位法 elem = self.driver.find_element_by_partial_link_text(value) else: raise ValueError('请输入正确的元素') return elem # 把定位方式的结果返回
#封装输入方法:
# 封装一个输入的方法
# 参数elem是元素定位结果, value是输入的内容
def sendkeys(self, elem, value):
return elem.send_keys(value)
# 封装一个点击的方法 def click(self, elem): return elem.click() # 封装一个打开网址的方法 def get(self, url): return self.driver.get(url) # 封装一个窗口最大化的方法 def maxwindow(self): return self.driver.maximize_window() # 封装一个获取文本的方法 def text(self, elem): return elem.text # 封装一个进入iframe框的方法 def iframe(self, elem): return self.driver.switch_to.frame(elem) # 封装一个退出浏览器 def quit(self): return self.driver.quit()
if name == ‘main’:
p = basepage()
utils工具包
1、报告模板:直接导入
2、邮件模板:直接修改,修改账号,授权码
3、读取配置文件readini
===========================================
pip install configparser 安装第三方库configparser
作用:在python中用来处理配置文件
代码:
from configparser import ConfigParser #导入ConfigParser类
from congfig.config import *
import os
class Readini(ConfigParser):
def init(self,filename):
ConfigParser.init(self) #继承父类构造方法
# 读取ini文件
self.read(filename) #self调用父类的read方法,传入路径读取文件
def read_ini(self,section=None,option=None): # 读取ini文件内容 value=self.get(section,option) #self调用父类的get方法,读取section和option return value利用路径获取data.ini文件
ini_path=os.path.join(data_path,‘data.ini’)
print(ini_path)read=Readini(ini_path) #创建对象
uat_test是文件头section,wangzhi是文件变量名option 获取data.ini文件里的wangzhiurl=read.read_ini(‘uat_test’,‘wangzhi’)
print(url) #http://cms.duoceshi.cn/cms/manage/login.do 获取data.ini文件里的zhanghaousername=read.read_ini(‘uat_test’,‘zhanghao’)
print(username) 获取data.ini文件里的mimapwd=read.read_ini(‘uat_test’,‘mima’)
print(pwd) ===========================================report报告层:
testcase 用例层
import unittest
from public.pages.basepage import *
from public.utils.Readini import *
from time import sleep
from selenium import webdriver
class Cms(unittest.TestCase):
# 初始化,打开浏览器
def setUp(self):
self.driver=webdriver.Chrome()
self.p=basepage()
self.p.setdriver(self.driver)
self.driver=self.p.getdriver()
# 登录
def test001_login(self):
self.p.get(url) #调用url
sleep(2)
self.p.maxwindow() #调用窗口最大化
sleep(2)
elems=self.p.find_elem(‘id’,‘userAccount’) #调用元素定位,定位账号输入框
self.p.sendkeys(elems,username) #输入账号
sleep(1)
elems=self.p.find_elem(‘id’,‘loginPwd’) #调用元素定位,定位密码输入框
self.p.sendkeys(elems,pwd) #输入密码
sleep(1)
elems=self.p.find_elem(‘id’,‘loginBtn’) #调用元素定位,定位登录按钮
self.p.click(elems) #点击登录
sleep(3)
elems=self.p.find_elem(‘class’,‘c-white’) #调用元素定位,定位登录后的用户名
name=self.p.text(elems) #调用取文本内容
assert name==‘超级管理员:admin’ #断言,匹配取到的文本是否跟 超级管理员:admin一致
# 查询 def test002_search(self): self.test001_login() #调用登录用例,减少代码重复 sleep(2) elems=self.p.find_elem('class','icon-user') #定位用户中心 self.p.click(elems) #点击用户中心 sleep(1) elems = self.p.find_elem('xpath','//*[@id="menu-user"]/dd/ul/li[1]/a') #定位用户管理 self.p.click(elems) #点击用户管理 sleep(2) elems= self.p.find_elem('name','/cms/manage/user-list.html') #定位iframe框 self.p.iframe(elems) #选择定位到的iframe框 sleep(2) elems=self.p.find_elem('id','searchValue') #定位到搜索输入框 self.p.sendkeys(elems,'dcs123456') #输入搜素内容 elems=self.p.find_elem('id','searchBtn') #定位搜索按钮 self.p.click(elems) #点击搜索按钮 elems=self.p.find_elem('class','text-primary')#调用元素定位,定位搜索结果的位置 name=self.p.text(elems) #获取结果文本 assert name=='dcs123456' #断言,匹配取到的文本是否跟搜索的结果一致 def tearDown(self): sleep(5) self.p.quit() #退出浏览器
if name==‘main’:
unittest.main()
===========================================
run层:运行层
作用:运行所有测试用例,输出测试报告,发送报告邮件