1.ddt简介:
Data-Driven Tests(DDT)即数据驱动测试。它允许您通过不同的测试数据来运行同一个测试用例,使它作为多个测试用例出现。其官方文档给出的定义如下:
DDT (Data-Driven Tests) allows you to multiply one test case by running it with different test data, and make it appear as multiple test cases.
DDT的经典使用场景之一是:测试用例的代码不变,只有测试数据在变化。简单来说就是测试数据的参数化。
ddt是第三方模块,使用前需要安装
pip install ddt
Python数据驱动模块DDT,包含类的装饰器ddt和两个方法装饰器data(直接输入测试数据)
通常情况下,data中的数据按照一个参数传递给测试用例,如果data中含有多个数据,以元组,列表,字典等数据,需要自行在脚本中对数据进行分解或者使用unpack分解数据。
@data(*参数)
拆分参数为多个,运行多次用例
@data(a,b)
那么a和b各运行一次用例
@data([a,d],[c,d])
如果没有 @unpack,那么[a,b]当成一个参数传入用例运行
如果有 @unpack,那么[a,b]被分解开,按照用例中的两个参数传递
2.data装饰器:
@data()是一个装饰器,它包含了您想提供给测试方法的值,个数和测试方法参数一样多。使用方法:在测试类(继承于unittest.TestCase)上面设置装饰器@ddt,在测试方法上设置装饰器@data()
例:
#coding:utf-8
import unittest
#从ddt模块导入装饰器ddt,file_data,unpack,data
from ddt import ddt,file_data,unpack,data
@ddt
#定义测试类BoolTest
class BoolTest(unittest.TestCase):
@data(1,"hello",3>2)
def test_true_001(self,value):
self.assertTrue(value)
@data("",1>2,{})
def test_false_002(self,value):
self.assertFalse(value)
if __name__ == "__main__":
unittest.main()
实际使用:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from PageObjects.login_page import LoginPage
from PageObjects.index_page import IndexPage
from TestDatas import login_data as lwd
from TestDatas import Comm_data
import unittest
import ddt
@ ddt.ddt
class TestLogin(unittest.TestCase):
#用例三步骤:前置,步骤,断言
def setUp(self):
#前置:打开网页,启动浏览器
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('{}Index/login.html'.format(Comm_data.base_url))
def tearDown(self):
self.driver.quit()
#正确登录成功
def test_login_success(self):
#步骤+断言
LoginPage(self.driver).login(lwd.success_data['phone'],lwd.success_data['password']) #登录
#断言
self.assertTrue(IndexPage(self.driver).check_name_exists()) #断言:判断为True
#断言二 --url的变化
self.assertEqual(self.driver.current_url,lwd.success_data['check'])
#异常登录--没有手机号、没有密码、手机号位数不对
@ddt.data(*lwd.wrong_data)
def test_login_failed_wrong_datas(self,data):
#登录操作
LoginPage(self.driver).login(data['phone'],data['password'])
#断言
self.assertEqual(LoginPage(self.driver).get_error_message_loginFrom(),data['check'])
#异常场景--错误手机号、密码错误
@ddt.data(*lwd.fail_data)
def test_login_failed_error_data(self,data):
#登录操作
LoginPage(self.driver).login(data['phone'],data['password'])
#断言
self.assertEqual(LoginPage(self.driver).get_error_message_pagetCenter(),data['check'])
3.unpack装饰器
依次传递元组、字典
#coding:utf-8
import unittest
#从ddt模块导入装饰器ddt,file_data,unpack,data
from ddt import ddt,file_data,unpack,data
#测试取绝对值函数abs()
@ddt
class AbsTest(unittest.TestCase):
@data({"val":1,"res":1},
{"val":0,"res":0},
{"val":-1,"res":1})
@unpack
def test_abs(self,val,res):
self.assertEqual(abs(val),res)
if __name__ == "__main__":
unittest.main()
列表
#测试取绝对值函数abs()
@ddt
class AbsTest(unittest.TestCase):
# @data({"val":1,"res":1},
# {"val":0,"res":0},
# {"val":-1,"res":1})
@data([-1,1],[0,0],[1,1])
@unpack
def test_abs(self,val,res):
self.assertEqual(abs(val),res)
if __name__ == "__main__":
unittest.main()
结果同上
4.file_data装饰器:
ddt支持从文件中加载数据,@file_data()装饰器会从json或yaml中加载数据。只有以“.yml” 和 “.yaml” 结尾的文件被加载为Yaml文件。所有其他格式文件都作为json文件加载,比如txt。修改示例3。
abs_data.json文件位于测试用例同级目录,内容如下:
{
"case1":{
"val":1,
"res":1
},
"case2":{
"val":-1,
"res":1
},
"case3":{
"val":0,
"res":0
}
}
#测试取绝对值函数abs()
@ddt
class AbsTest(unittest.TestCase):
# @data({"val":1,"res":1},
# {"val":0,"res":0},
# {"val":-1,"res":1})
@file_data("./abs_data.json")
def test_abs(self,val,res):
self.assertEqual(abs(val),res)
if __name__ == "__main__":
unittest.main()
使用数据驱动思想编写测试用例有以下优势:
测试代码和测试数据分开,比较灵活,易维护。
在测试代码相对健壮的情况下,新增用例只需新增测试数据即可,开发难度小。
避免编写大量相同的测试代码,代码复用率高