unittest 和 ddt 有很好的契合度,ddt读取的数据可以直接用于unittest。
4.1 ddt.data直接传参
import unittest # python自带,不需要额外安装
from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
from web_key_demo import KeyDemo
@ddt # 装饰ddt来声明我要用这个ddt来管理测试类
class CaseDemo(unittest.TestCase):
# 在测试用例执行前先执行
def setUp(self) -> None:
print('+++++++++++++++++++++++++++++++++++')
pass
# 测试用例执行后紧接着执行
def tearDown(self) -> None:
print('------------------------------------')
pass
# ======================================================= ddt的data直接传参 =======================================
@data('隔壁老王') # 单个传参
def test_01(self,name):
print(name)
@data(['隔壁老赵','嘿咻嘿咻']) # 多个参数
@unpack # 多个参数需要这样解压
def test_02(self, name, action):
print(name)
print(action)
@data(['隔壁老王', '睡觉'],['隔壁老李', '幽会']) # 多组数据,每组多个参数,几组数据执行几次函数
@unpack # 需要这样解压
def test_03(self, name, action):
print(name)
print(action)
if __name__ == '__main__':
unittest.main()
"""
+++++++++++++++++++++++++++++++++++
隔壁老王
------------------------------------
+++++++++++++++++++++++++++++++++++
隔壁老赵
嘿咻嘿咻
------------------------------------
+++++++++++++++++++++++++++++++++++
隔壁老王
睡觉
------------------------------------
+++++++++++++++++++++++++++++++++++
隔壁老李
幽会
------------------------------------
Ran 4 tests in 0.013s
OK
"""
4.2 ddt模块读取yaml文件
第三节代码可以发现,测试用例01和02只是数据不同,可以采取数据驱动。
首先需要安装ddt和PyYAML模块,用ddt读取yaml数据文件中一组一组数据为一个个的字典,逐个传入测试用例来执行。
import unittest
from 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()
yaml文件 数据层:
- # 一个符号表示一组数据,ddt读取后是一个字典
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
五、测试套件
测试套件就是测试用例的集合,我们添加什么用例他就包含什么,执行顺序按照添加顺序。
unittest.main()只能以默认顺序执行所有的测试用例,可以用到测试套件来执行一部分测试用例,并且顺序可以指定。
注意:测试套件的代码必须另外一个文件,不能直接写在测试用例文件的main内。
import unittest # python自带,不需要额外安装
from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
@ddt # 装饰ddt来声明我要用这个ddt来管理测试类
class CaseDemo(unittest.TestCase):
# 如果希望从外边向测试用例类传参,就需要调用父类的init,从源码可以看到父类只有methodName='runTest'这么一个参数
def __init__(self, methodName='runTest',wechat=None):
super().__init__(methodName=methodName)
self.wechat = wechat
# 在测试用例执行前先执行
def setUp(self) -> None:
print('+++++++++++++++++++++++++++++++++++')
# 测试用例执行后紧接着执行
def tearDown(self) -> None:
print('------------------------------------')
def test_01(self):
"""test_01:注释可以显示在报告的描述信息中
"""
print('print信息可以显示在成功的用例的测试报告中')
@data('隔壁老王') # 单个传参
def test_03(self, name):
print(name)
@unittest.skip('我无条件跳过,就无条件跳过')
def test_skip1(self):
"""test_skip1:注释可以显示在报告的描述信息中
"""
print('test_skip1我还有机会BB么??')
def test_assert(self):
"""'断言测试,msg是断言失败后提示信息,可以不要'
"""
def _test():
return '老王'
res = _test()
# 各种断言的方法都是内置属性,可以选择合适的来用
self.assertEqual(res,'老赵', msg=f'不是老赵干的别冤枉他,是{res}干的') # 断言value1 == value2
# # 失败后返回 AssertionError: '老王' not found in ['老张', '老李'] : 老王不在嫌疑人里面里面,不是他
# self.assertIn(res,['老张','老李'],msg=f'{res}不在嫌疑人里面里面,不是他')
# # 失败后返回: '老王' is not false : 返回不是False
# self.assertFalse(res,msg='返回不是False')
if __name__ == '__main__':
unittest.main()
# # 在这个测试用例的main中这样添加套件,执行后你会发现还是执行了所有,并不是只执行了套件中添加的几个用例
# # 在测试类的main函数中默认执行unittest.main()方法,套件不会生效,套件必须生成新的对象,即另外建立文件导入CaseDemo类来构建
# import unittest
# # 构造测试集
# suite = unittest.TestSuite()
# # 添加测试用例
# suite.addTest(CaseDemo('test_skip1'))
# suite.addTest(CaseDemo('test_assert'))
# # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
# # 执行测试
# runner = unittest.TextTestRunner()
# runner.run(suite)
case_demo03
添加测试套件有很多种方法,见下:(测试套件可以给测试用例传参,方法见test_skip1)
import unittest
from case_demo03 import CaseDemo
from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
#构造测试集
suite = unittest.TestSuite()
# 套件添加测试用例 +++++++++++++++++++++++++++++++++++++++++++++++++++
# # 第一种方法:逐个添加
# # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
# suite.addTest(CaseDemo('test_skip1',wechat=666)) # 可以重写CaseDemo的init方法,就可以传参数过去
# suite.addTest(CaseDemo('test_assert'))
# 第二种方法:列表添加多个
cases = [CaseDemo('test_skip1',wechat='我是额外的参数'),
CaseDemo('test_01'),
CaseDemo('test_assert'),
]
suite.addTests(cases)
#
# # 第三种方法:批量添加测试用例类
# # 会执行路径下所有名字符合'case_demo*.py'的所有文件下测试用例类的所有测试用例
# execute_path = './'
# suite = unittest.defaultTestLoader.discover(start_dir=execute_path, pattern='case_demo*.py', top_level_dir=None)
# # 第四种方法:基于类对象添加测试用例类
# # 会执行类下面所有的测试用例
# suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CaseDemo))
# # 第五种方法:基于类名称添加测试用例类
# # 会执行类下面所有的测试用例
# suite.addTests(unittest.TestLoader().loadTestsFromName('case_demo03.CaseDemo'))
# # 还有其他方法,用unittest.TestLoader()可以点出来
# unittest.TestLoader().loadTestsFromModule()
# unittest.TestLoader().loadTestsFromNames()
if __name__=='__main__':
# 执行测试套件
runner = unittest.TextTestRunner()
runner.run(suite)
六、python使用BeautifulReport形成测试报告
对于测试用例的执行结果,我们可以使用beautifulreport来生成美观的html测试报告,经过使用,总结以下特点:
1.执行失败的错误信息可以直接显示在详情里面。
2.执行成功的结果可以通过print来输出,就可以显示在测试报告详情里。
3.测试用例的注释信息可以显示在报告中描述一栏。
用法很简单,见下:
import unittest
from case_demo03 import CaseDemo
from ddt import ddt,data,file_data,unpack # 需要 pip install ddt
#构造测试集
suite = unittest.TestSuite()
# 套件添加测试用例 +++++++++++++++++++++++++++++++++++++++++++++++++++
# # 第一种方法:逐个添加
# # suite.addTest(CaseDemo('test_03')) # 这个test_03用了ddt传参,不会运行。。。不知为何
# suite.addTest(CaseDemo('test_skip1',wechat=666)) # 可以重写CaseDemo的init方法,就可以传参数过去
# suite.addTest(CaseDemo('test_assert'))
# 第二种方法:列表添加多个
cases = [CaseDemo('test_skip1',wechat='我是额外的参数'),
CaseDemo('test_01'),
CaseDemo('test_assert'),
]
suite.addTests(cases)
#
# # 第三种方法:批量添加测试用例类
# # 会执行路径下所有名字符合'case_demo*.py'的所有文件下测试用例类的所有测试用例
# execute_path = './'
# suite = unittest.defaultTestLoader.discover(start_dir=execute_path, pattern='case_demo*.py', top_level_dir=None)
# # 第四种方法:基于类对象添加测试用例类
# # 会执行类下面所有的测试用例
# suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CaseDemo))
# # 第五种方法:基于类名称添加测试用例类
# # 会执行类下面所有的测试用例
# suite.addTests(unittest.TestLoader().loadTestsFromName('case_demo03.CaseDemo'))
# # 还有其他方法,用unittest.TestLoader()可以点出来
# unittest.TestLoader().loadTestsFromModule()
# unittest.TestLoader().loadTestsFromNames()
if __name__=='__main__':
# # 执行测试套件
# runner = unittest.TextTestRunner()
# runner.run(suite)
# 使用BeautifulReport执行套件并生成测试报告
from BeautifulReport import BeautifulReport
result = BeautifulReport(suite)
# filename:测试报告报告名字
# description:测试用例名字,会显示在图文进面
# report_dir:报告存储路径,没有会自动创建
# theme:默认即可,可不写
result.report(filename='wxbot原子操作测试报告', description='测试deafult报告', report_dir='report', theme='theme_default')
生成的报告如下图:
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理