四、数据驱动 + 关键字驱动 Selenium二次封装与集成(Unittest+ddt+PyYMAL) 1.关键字驱动主要应用方向和优点: 对于多系统的复用性,一套代码可支持多系统,POM只能支持单一系统 简化代码降
四、数据驱动 + 关键字驱动 Selenium二次封装与集成(Unittest+ddt+PyYMAL)
1.关键字驱动主要应用方向和优点:对于多系统的复用性,一套代码可支持多系统,POM只能支持单一系统
简化代码降低冗余,提升复用性、可维护性
2.关键字驱动体系下的结构:
1.逻辑代码 web_key_demo.py
2.测试代码 case_demo03.py
3.测试数据 search.yaml
基于 数据驱动 + 关键字驱动 实现的自动化测试效果。
4.1 关键字驱动类(逻辑层)
对于线性代码进行封装,这样我们就得到封装后的方法
# web_key_demo.py +++++++++++++++++++++++++++++"""
关键字驱动类:底层逻辑代码,这个类不会直接执行测试行为。
属于逻辑层代码,常规的操作行为封装成自定义的关键字函数。
在执行自动化的时候,通过调用自定义函数类,来实现自动化测试操作。
常规操作行为:
1.创建浏览器对象
2.访问url
3.元素定位
4.输入
5.点击
6.其他...
"""
from selenium import webdriver
#基于type生成对应的浏览器对象
def browser(type_):
try:
# driver本身只限于webdriver对象
driver = getattr(webdriver,type_)()
except Exception as e:
driver = webdriver.Chrome()
return driver
class KeyDemo:
def __init__(self, type_):
self.driver = browser(type_)
#访问url
def open(self,url):
self.driver.get(url)
#元素定位:8种元素定位
def locator(self,name,value):
return self.driver.find_element(name,value)
#输入
def input(self, name,value,txt):
self.locator(name, value).send_keys(txt)
#点击
def click(self, name,value):
self.locator(name,value).click()
#关闭浏览器
def quit(self):
self.driver.quit()
# 睡眠
def sleep(self,time_):
time.sleep(time_)
逻辑代码 web_key_demo.py
4.2 测试用例(unittest初探)
基于封装后的方法线性代码可以这样写:
# case_demo.py ++++++++++++++++++++++++++from web_key_demo import KeyDemo
kd = KeyDemo('Chrome')
kd.open( ' http://www.baidu.com ' )
kd.input( 'id', 'kw','美女')
kd.click( 'id' , 'su')
kd.sleep(3)
kd.quit()
View Code
对于多个测试用例可以引入unittest管理:
# case_demo02.py ++++++++++++++++++++import unittest
from web_key_demo import KeyDemo
class CaseDemo(unittest.TestCase):
def test_01(self): # 测试用例名字需要以test开头
kd = KeyDemo('Chrome')
kd.open(' http://www.baidu.com ')
kd.input('id', 'kw', '美女')
kd.click('id', 'su')
kd.sleep(3)
kd.quit()
def test_02(self):
kd = KeyDemo('Chrome')
kd.open(' http://www.baidu.com ')
kd.input('id', 'kw', '妹子')
kd.click('id', 'su')
kd.sleep(3)
kd.quit()
if __name__ == '__main__':
unittest.main() # 只要运行这个,就会逐个运行CaseDemo下test开头的方法,如test_01和test_02
unittest初识 case_demo02.py
4.3 数据层(unittest + ddt + yaml)
上面代码可以发现测试用例01和02只是数据不同,可以采取数据驱动
unittest 和 ddt 有很好的契合度,ddt读取的数据可以直接用于unittest
首先需要安装ddt和PyYAML模块,用ddt读取yaml数据文件中一组一组数据为一个个的字典,逐个传入测试用例来执行
# case_demo03.py ++++++++++++++++++++import unittest
from ddt import ddt,file_data
from web_key_demo import KeyDemo
@ddt # 装饰ddt来管理测试类
class CaseDemo(unittest.TestCase):
@file_data('./data/search.yaml') # ddt模块读取文件中数据转化为一组一组数据传入测试用例
def test_01(self, url, _input, click): # 测试用例名字需要以test开头
kd = KeyDemo('Chrome')
kd.open(url)
kd.input(**_input)
kd.click(**click)
kd.sleep(3)
kd.quit()
if __name__ == '__main__':
unittest.main()
unittest +ddt
代码还可以简化为:
import unittestfrom ddt import ddt,file_data
from web_key_demo import KeyDemo
@ddt # 装饰ddt来管理测试类
class CaseDemo(unittest.TestCase):
# 在测试用例执行前先执行
def setUp(self) -> None:
self.kd = KeyDemo('Chrome')
# 测试用例执行后紧接着执行
def tearDown(self) -> None:
self.kd.quit()
@file_data('./data/search.yaml') # ddt模块读取文件中数据转化为一组一组数据传入测试用例
def test_01(self, url, _input, click): # 测试用例名字需要以test开头
self.kd.open(url)
self.kd.input(**_input)
self.kd.click(**click)
self.kd.sleep(3)
if __name__ == '__main__':
unittest.main()
测试代码 case_demo03.py
url : http://www.baidu.com
_input:
name: id # _input下的一组数据,读取后字典键值对的value是一个字典
value: kw
txt: 美女
click:
name: id
value: su
-
url : http://www.baidu.com
_input:
name: id
value: kw
txt: 妹子
click:
name: id
value: su
-
url : http://www.jd.com
_input:
name: id
value: key
txt: 不可描述的好东西
click:
name: xpath
value: //button[@aria-label='搜索']
数据层 search.yaml
注意执行的时候光标不能放入CaseDemo类中,需要放到外面,点一下其他位置再执行,不然会报错
AttributeError: type object 'CaseDemo' has no attribute 'test_01'
ErrorTraceback (most recent call last):
File "E:\python3.8\lib\unittest\case.py", line 60, in testPartExecutor
yield
File "E:\python3.8\lib\unittest\case.py", line 676, in run
self._callTestMethod(testMethod)
File "E:\python3.8\lib\unittest\case.py", line 633, in _callTestMethod
method()
File "E:\python3.8\lib\unittest\loader.py", line 34, in testFailure
raise self._exception
File "E:\python3.8\lib\unittest\loader.py", line 169, in loadTestsFromName
parent, obj = obj, getattr(obj, part)
AttributeError: type object 'CaseDemo' has no attribute 'test_01'
View Code