一、介绍自动化测试框架和pom模型
1、自动化测试框架是一个集成体系,这个体系包含测试功能的函数,测试数据源,测试对象以及重要的模块。
2、作用:用于解决和处理复杂问题
3、线性脚本的自动化测试在维护性和可用性上较差,所有就设计框架来实现自动化测试。
4、框架的设计目标:
(1)设计出来的框架是直接给测试人员或其他测试人员简单向里面不断补充用例,所以我们在框架设计必须三简化:
操作操作,维护简单,拓展简单
(2)设计框架的同时要结合业务流程,不仅靠技术实现,还要对业务流程的理解和把握(重点和难点)
(3)设计框架要将基础的方法封装成公用的:如:定位方法,断言等
(4)设计用例要与代码分开,便于管理,可以采取数据驱动实现,(比如ddt数据驱动等)
========================================================================
二、po框架
(1)po (page object缩写)
(2)业务流程与页面元素操作分离模式,可以简单理解为每个页面下面都有一个配置的class,配置class 就是用来维护页面元素或操作方法
(3)提高测试用例的可维护性和可读性
(4)对比传统的设计测试用例存在弊端:
a、易读性差
b、维护性差
c、复用性差
d、拓展性差
=======================================================
po模型的分层格式:
第一个包config包 :配置包,存放项目配置文件,如框架中每个目录的绝对路径
第二个包 data 包:数据包, 存放测试数据,一般以ini文件类型存放
第三个包public 包:公共包,
两个子包:一个是: pages包,另一个是 utils 包
第四个report 包:报告包 存放测试报告
第五个包:run 包: 运行包 运行测试用例
第六个包:testcase 包: 用例包 存放所有测试用例
=======================================================
实战:
一、新建六个包
二、第一个包cms_config 包
这个模块用来存放项目中所有目录的绝对路径
第二个包:data包
第三包:public公共包
第一个子包:cms_basepage
cms_basepage :这个模块用来封装公共方法,比如元素定位、控件、按钮、线程等待、窗口最大化等
定位元素:
方法:
另一个子包:utils包
1、将报告模板导入
2、将邮件模板导入
3、读取ini文件模块
readini文件:
'''这个模块用来读取ini配置文件
配置文件格式一般有:.ini、.conf、.xlsx、.xls、.cnf、.csv、.yaml
注意点:
导入的ConfigParser类,
在去读取data数据包的参数
from configparser import ConfigParser #导入ConfigParser类
from hz1010.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文件里的wangzhi
url=read.read_ini('uat_test','wangzhi')
print(url) #http://cms.duoceshi.cn/cms/manage/login.do
# 获取data.ini文件里的zhanghao
username=read.read_ini('uat_test','zhanghao')
print(username)
# 获取data.ini文件里的mima
pwd=read.read_ini('uat_test','mima')
print(pwd)
第四个包:report包 报告包
第五包:
'''这个模块用来运行所有测试用例,输出测试报告,发送报告邮件'''
from hz1010.congfig.config import *
from time import sleep,strftime
from hz1010.public.utils.HTMLTestRunnerNew import *
from hz1010.public.utils.mail3 import *
# 用例所在文件的路径
dir = r'C:\Users\Administrator\PycharmProjects\hz15_po\hz1010\testcase'
# 报告生成时间取当前时间
time = time.strftime('%Y-%m-%d-%H-%M-%S')
# 测试报告存放路径+报告生成时间及报告文件名称
filename = report_path + '\\' + str(time) + ' ui_report.html'
f = open(filename, 'wb') # 打开报告文件,二进制写入内容
# discover()里面参数start_dir接路径,pattern接文件名,支持模糊查询
def auto_run():
aa = unittest.defaultTestLoader.discover(start_dir=dir, pattern='testcase.py')
runner = HTMLTestRunner(stream=f, # 接打开的文件
title='自动化测试报告',
description='自动化运行情况',
tester='小肖')
runner.run(aa)
f.close()
def sendmail():
# 参数send_msg接文件名,呈现文件内容,参数attachment接文件,作为附件传输
sm=SendMail(send_msg=filename,attachment=filename)
sm.send_mail() #发送邮件
if __name__=='__main__':
auto_run()
sendmail()
==============================================
第六个包:testcase包
# po分层设计 全称:pageobject
# 一、po框架:页面对象的设计模式
#
# 二、优点:
# 1.元素、公共方法、用例都可以分离,进行分开管理
# 2.代码之间进行解耦
# 3.能提高代码的复用性和灵活性
#
# 三、缺点:代码量多,复杂性高
#
# 四、设计的过程
# 创建一系列相关的目录和python package包(文件夹),将相关的代码进行管理
#
'''这个模块是写测试用例的'''
import unittest
from hz1010.public.pages.basepage import *
from hz1010.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,'hz10') #输入搜素内容
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=='hz10' #断言,匹配取到的文本是否跟搜索的结果一致
def tearDown(self):
sleep(5)
self.p.quit() #退出浏览器
if __name__=='__main__':
unittest.main()