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设计模式就可以将测试脚本调到最优...

 

posted @ 2019-12-20 11:23  风车车与车车风  阅读(1555)  评论(0编辑  收藏  举报