python自动化过程中的数据驱动以及关键字驱动
python自动化过程中的数据驱动以及关键字驱动
我们公司最近一直在推自动化,意在提高测试效率,减少在回归过程中的大量重复发工作量。UI自动化靠的是seleniumIDE的录制配合导出的py文件结合unittest来做简单的自动化。但是在实现中可能为遇到这样一个问题,一个页面存在大量表单填写,或者同一个流程需要填写不同的参数进行测试时,我们总不可能重新录制一遍流程,或者在已经录制好的脚本中一条数据一条数据的去改动,这个时候我们就需要结合数据驱动来优化我们的脚本。
数据驱动以及关键字驱动:
关键字驱动:比如在我们公司的推的UI自动化场景中,将录制好的脚本封装成函数,结合unittest调用,这样的方式实现测试动作,就是关键字驱动。封装好的函数就可看成是关键字。甚至可以这样理解,函数式编程就是关键字驱动。在测试框架中最出名的关键字驱动框架应该RobotFramework框架,这款框架其实还挺不错的,也是一定程度上降低了自动化的代码能力的要求(测试脚本的组装过程),但是关键字的封装过程还是有些难度的。这框架跟我们国产的编程语言:易语言有些相像,有兴趣的小伙伴可以自行了解一下。
数据驱动:还是这个场景,我们将封装好的函数,每次调用只能满足一个特定的测试场景,而且维护起来很麻烦,就算将函数中需要输入的值参数化,放在其他地方(比如csv文件,列表,元祖...)这也只是减少了维护的成本,优化了代码。要是进一步的通过提前准备好的数据,让脚本根据准备好的数据来进行不同场景的业务覆盖,那么我们就实现了最简单数据驱动测试...
数据驱动测试实现:
举两个个小例子让大家了解什么是数据驱动,以及如何实现。
1、简单的数据驱动测试:
业务场景:周报考勤系统的登录(登录操作的测试:1、正确用户名密码; 2、正确用户名,错误密码;3、错误的用户名,密码)
实现:需要用到python中的ddt库,为了创建数据驱动测试,我们需要在测试类上使用@ddt装饰符,在测试方法上使用@data装饰符。@data装饰符把参数当作测试数据,参数可以是单个值、列表、元组、字典。对于列表,需要用@unpack装饰符把元组和列表解析成多个参数。
#python的单元测试框架 import unittest #python用来实现数据驱动的库ddt(pip install ddt 即可安装下载) from ddt import ddt, data, unpack #selenium 实现UI自动化 from selenium import webdriver import time @ddt #@ddt装饰符,在测试方法上使用@data装饰符 class LearnDDT(unittest.TestCase): #测试用例的前置动作 def setUp(self) -> None: #实例化一个浏览器驱动 self.driver = webdriver.Chrome() self.driver.implicitly_wait(30) #隐式等待时间 self.driver.maximize_window() #窗口最大化 self.driver.get('http://kq.thunisoft.com:8080/kqgl/logout') #打开登录地址 #@data装饰符把参数当作测试数据,参数可以是单个值、列表、元组、字典 @data(('right_name', 'right_passwdl'), ('right_name', 'wrong_passwd'), ('wrong_name', 'right_passwd')) #提前准备好的测试数据 # @unpack装饰符把元组和列表解析成多个参数 @unpack def test_login(self, name, passwd): ''' 把下面的三步操作封装成函数,再在case中调用该函数,就可以理解为关键字驱动,调用的函数名就是关键字。 def login(name, passwd) self.driver.find_element_by_name('j_username').send_keys(name) self.driver.find_element_by_name('j_password').send_keys(passwd) self.driver.find_element_by_id('submit_button').click() ''' self.driver.find_element_by_name('j_username').send_keys(name) #输入用户名 self.driver.find_element_by_name('j_password').send_keys(passwd) #输入密码 self.driver.find_element_by_id('submit_button').click() #点击登录 time.sleep(5) #测试用例的后置动作 def tearDown(self) -> None: self.driver.quit() #退出浏览器操作 if __name__ == '__main__': main = unittest.main(verbosity=2)
运行该测试脚本,则会使用列表中三组数据,分别覆盖业务场景。用一套代码,覆盖到了不同的业务场景。
2、还是简单的数据驱动测试(将数据存在csv文件中):
业务场景:还是周报考勤系统的登录(登录操作的测试:1、正确用户名密码; 2、正确用户名,错误密码;3、错误的用户名,密码)
实现:还是用到了ddt库,但是这次将数据存在csv文件中,就像这样:
封装从一个函数:专门中csv文件中获取数据(这里不限于csv文件,可以是excel,txt等等文件)
import csv #引入操作csv文件的库 def get_data(filename): datas = [] #创建一个空列表接收数据 with open(filename, 'r') as f: #读取csv文件 reader = csv.reader(f) #创建csv实例化对象 next(reader) #去除头部信息 for row in reader: datas.append(row) return datas
测试场景覆盖:(代码和上面的那段几乎没有变动,唯一变得是@data装饰符后面跟的参数)
from ddt import ddt, data, unpack
import time
from selenium import webdriver
import unittest
@ddt
class LearnDDT2(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get('http://kq.thunisoft.com:8080/kqgl/logout')
@data(*get_data("login.csv")) #调用获取测试数据的函数,由于传入的是个列表,所以前面需要加上“ * ”。
@unpack
def test_login2(self, name, passwd):
self.driver.find_element_by_name('j_username').send_keys(name)
self.driver.find_element_by_name('j_password').send_keys(passwd)
self.driver.find_element_by_id('submit_button').click()
self.assertEqual()
time.sleep(5)
def tearDown(self) -> None:
self.driver.quit()
if __name__ == '__main__':
main = unittest.main(verbosity=2)
有兴趣的小伙伴,可以自己实验一下,让后运行脚本,看看到底是怎样的一个效果。这样会帮你更加了解什么是数据驱动测试。当然这只是最简单的数据驱动测试。仅单单从测试数据入手,其实还可以实现更复杂的业务场景,再结合PO设计模式就可以将测试脚本调到最优...