前言
DDT(Data-Driven Tests)是针对 unittest 单元测试框架设计的扩展库。允许使用不同的测试数据来运行一个测试用例,并将其展示为多个测试用例。通俗理解为相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动。相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为完全分离, 这样的测试脚本设计模式称为数据驱动。
实施数据驱动步骤
我们再来说说实施数据驱动测试的步骤:
1.创建/准备测试数据
2.封装读取数据的方法,保留测试脚本调用的接口/属性(我们需要传递给脚本什么参数)
3.编写自动化测试脚本
4.脚本中调用封装好的处理数据文件的模块并引入测试数据
5.执行测试脚本并分析测试结果
数据驱动测试环境准备
GitHub 地址:https://github.com/datadriventests/ddt。
DDT 支持 pip 安装:pip install ddt
测试步骤
1.访问地址:https://mail.sohu.com/fe/#/login
2.输入用户名和密码
3.点击登录按钮
4.判断是否登录成功
数据存储
方法1:数据存在当前脚本中
1 # -*- coding:GBK -*-
2 # 导入测试所需模块
3 import time
4 import unittest
5 from selenium import webdriver
6 from ddt import ddt, data, unpack
7 from selenium.common.exceptions import NoSuchElementException
8
9 """
10 简单额数据驱动测试
11 """
12 @ddt #@ddt来装饰测试类(ddt数据驱动的规范写法,记住就ok)
13 class DDT_TEST(unittest.TestCase):
14 # 数据可以是元祖、列表、字典
15 value =[['13691579846@sohu.com', 'xiaochao11520','https://mail.sohu.com/fe/#/homepage'],
16 ['13691579844@sohu.com', 'xiaochao11520','https://mail.sohu.com/fe/#/homepage']]
17
18 def setUp(self):
19 self.driver = webdriver.Firefox()
20 self.login_url = 'https://mail.sohu.com/fe/#/login'
21 self.driver.get(self.login_url)
22
23 @data(*value) # 解析数据
24 @unpack # 用来解包, 将每组数据的第一个数据传递给uname依次类推, 当数据为字典时,形参需和字段的key值相同
25 def test_case1(self, uname, passwd, expected):
26 try:
27 username = self.driver.find_element_by_xpath("//input[@placeholder='请输入您的邮箱']")
28 username.send_keys(uname)
29 time.sleep(2)
30 userpassword = self.driver.find_element_by_xpath("//input[@placeholder='请输入您的密码']")
31 userpassword.send_keys(passwd)
32 time.sleep(2)
33 self.driver.find_element_by_xpath("//input[@type='submit']").click()
34 time.sleep(2)
35 currenturl = self.driver.current_url
36 self.assertEqual(expected, currenturl, '登录失败')
37 except NoSuchElementException as e:
38 print(e)
39 raise
40 except ArithmeticError:
41 print('期望值是{},实际值是{}'.format(expected, currenturl))
42 raise
43 except Exception:
44 raise
45
46 def tearDown(self):
47 self.driver.quit()
48 # pass
49
50
51 if __name__ == "__main__":
52 unittest.main(verbosity=2)
源码分析
1.@ddt来装饰测试类(ddt数据驱动的规范写法,记住就ok)
2.@data(*value)装饰测试用例(也是一种规范,这边又涉及到装饰器,不懂的可以百度或者看我之前的文章又介绍,这边不再赘述,一句话两句话也说不清楚)记住:*value作用是打散数据,比如上面代码是用一个大列表存储两个小列表存放数据的,那么*value会得到两个小列表,每个小列表是一组测试数据
3.@unpack 解析*value数据,会把两个小列表里面的每一个数据取出来分别传递给我们测试用例的形参
方式1缺点
存储大量数据时,需查看源代码,不利于脚本的维护
方法2:json或txt文件读取测试数据进行数据驱动测试
新建一个json文件(也可以是txt文件),将我们需要的两组测试数据以列表的形式写到json文件中,每组数据的每一项参数用相同的符号分割开(方便脚本读取数据)
{
"value1":"13691579846@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage",
"value2":"13691579844@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage"
}
1 # -*- coding:GBK -*-
2 # 导入测试所需模块
3 import unittest
4 from time import sleep
5 from ddt import ddt, file_data
6 from selenium import webdriver
7 from HTMLTestRunner import HTMLTestRunner
8 from selenium.common.exceptions import NoSuchElementException
9
10 """
11 从文件中读取测试数据
12 """
13 @ddt # ddt装饰测试类
14 class TestJsonData(unittest.TestCase):
15
16 def setUp(self):
17 self.driver = webdriver.Firefox()
18 self.driver.get("https://mail.sohu.com/fe/#/login")
19
20 @file_data('json_data.json') # 读取文件的 文件中数据可以是一个列表,也可以是一个字典
21 def test_data(self, value):
22 uname,passwd,expected = tuple(value.strip().split("||")) # value是一个字符串
23 try:
24 username = self.driver.find_element_by_xpath('//input[@placeholder="请输入您的邮箱"]')
25 username.send_keys(uname)
26 sleep(2)
27 password = self.driver.find_element_by_xpath('//input[@placeholder="请输入您的密码"]')
28 password.send_keys(passwd)
29 sleep(2)
30 self.driver.find_element_by_xpath('//input[@type="submit"]').click()
31 sleep(2)
32 currenturl = self.driver.current_url
33 self.assertEqual(expected, currenturl, "登录失败")
34 except NoSuchElementException as e:
35 print(e)
36 raise
37 except AssertionError:
38 print("期望值是{},实际值是{}".format(expected, currenturl))
39 except Exception:
40 raise
41 def tearDown(self):
42 self.driver.quit()
43
44
45 if __name__ == "__main__":
46 unittest.main(verbosity=2)
源码分析
1.相对上个实例,这里使用了@file_data(文件路径), 参数必须是一个文件,这里是一个json文件, 数据可以是一个列表,也可以是一个字典
# 列表形式
[
"*******@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage",
"*******@sohu.com||xiaochao11520||https://mail.sohu.com/fe/#/homepage"
]
2.测试用例接收的是一个字符串,需要对字符串进行处理,把用户名,密码,期望值解析出来
3.测试数据存在文件中,方便管理修改,添加数据,易于维护
总结
看了上面的实例对于步骤应该还算合理,下面是我在网上找到的数据驱动测试步骤(感觉比较官方!大家可以参考)
1.编写测试脚本, 脚本需要支持从程序对象, 文件,或者数据库读入数据。(个人观点:如果脚本先编写完,测试数据还未准备,后期还要做修改)
2.将测试脚本使用的测试数据存入程序对象,文件,或者数据库等外部介质中。(个人观点:这个阶段实为准备数据的阶段,也就是我们数据要存在哪里,理应放在第一步)
3.运行脚本过程中,循环调用存储在外部介质中的测试数据。(个人观点:这里要考虑我们如何读取,使用数据)
4.验证所有的测试结果是否符合预期结果