""" 通过断言判断用例是否成功 """ import unittest class Test(unittest.TestCase): def test01(self): a = 'hello' b = 'hello' self.assertEqual(a, b) def test02(self): a = 'Python' b = 'Python自动化' self.assertIn(a, b) def test03(self): a = 'Python' b = 'Python自动化' self.assertNotIn(a, b, msg='报错原因,%s没有包含%s' % (a, b)) if __name__ == '__main__': unittest.main()
# 数据驱动ddt
在设计用例时候,有些用例参数数据输入不一样。操作过程是一样的,如果用例重复去写操作过程会增加代码量,
对于多组数据的测试用例,可以用数据驱动设计模式,一组数据对应一个测试用例,用例自动加载生成。
安装ddt模块:pip install ddt
数据驱动原理
- 测试数据为多个字典的list类型
- 测试类前加修饰 @ ddt.ddt
- case前加修饰 @ ddt.data()
- 运行后用例会自动加载成三个单独的用例
@data(a,b)
那么a和b各运行一次用例
@data([a,d],[c,d])
如果没有@unpack,那么[a,b]当成一个参数传入用例运行
如果有@unpack,那么[a,b]被分解开,按照用例中的两个参数传递
def readFile(): # 定义一个list集合 params = [] file = open('ppp.yml', 'r', encoding='gbk') for line in file.readline(): params.append(line.strip('\n').split(',')) return params @ddt class TestCase(unittest.TestCase): def setUp(self) -> None: self.driver = webdriver.Chrome() self.driver.get("http://www.baidu.com") def tearDown(self) -> None: time.sleep(2) self.driver.quit() @data("Java", "Python") def test_01(self, txt): self.driver.find_element_by_id("kw").send_keys(txt) self.driver.find_element_by_id("su").click() @data(("30而立", "加油"), ("奥力给", "哈哈")) @unpack def test_02(self, args, args1): print(args) print(args1) @file_data('ppp.yml') def test_03(self, **kwargs): # 获取参数中key为name的value print(kwargs.get('name')) # key为text的value print(kwargs.get('job')) if __name__ == '__main__': unittest.main()
# Python ddt 实现数据驱动(案例一)
import unittest from ddt import ddt,data,unpack @ddt class MyTesting(unittest.TestCase): def setUp(self): print('this is the setUp') @data([1,2,3]) def test_1(self,value): print(value) @data([3,2,1],[5,3,2],[10,4,6]) @unpack def test_minus(self,a,b,expected): actual = int(a) - int(b) expected = int(expected) self.assertEqual(actual, expected) @data([2,3],[4,5]) def test_compare(self,a,b): self.assertEqual(a,b) def tearDown(self): print('this is tearDown') if __name__ == '__main__': unittest.main(verbosity=2)
# Python ddt数据驱动二(json,yaml驱动)
① 通过json文件驱动
@ddt class MyTest(unittest.TestCase): @file_data('test_data_list.json') def test_data_list(self,value): print(value) @file_data('test_data_dict.json') def test_data_dict(self,value): print(value)
② 通过yaml文件驱动
pip install pyyaml进行安装
直接import yaml,右键运行py文件,不报错,则为导入成功。
1.PyYaml简介
YAML是一种容易阅读、适合表示程序语言的数据结构、可用于不同程序间交换数据、丰富的表达能力和可扩展性、易于使用的语言。通过缩进或符号来表示数据类型。
Yaml提供了多种方法,常用的为yaml.load和yaml.dump。
2.基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
#
表示注释,从这个字符一直到行尾,都会被解析器忽略,这个和python的注释一样
3.PyYaml文件编写格式
yaml文档除了可以通过dump进行转化之外,也可以根据yaml文档的格式进行编写。
- 对象的一组键值对,使用冒号结构表示。
- 一组减号开头的行,构成一个list。
- 对象和数组可以结合使用,形成复合结构。
- ~ 代表None
- 布尔类型 直接写bool: True False
4.YAML 支持的数据结构有三种:
1、对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
2、数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
3、纯量(scalars):单个的、不可再分的值。字符串、布尔值、整数、浮点数、Null、时间、日期
import yaml # 写入yaml文件 # yaml.dump 将一个Python对象生成为yaml文档。参数一为要转为yaml文档的数据,参数二必须为一个已经打开的文件对象。 with open('dump.yml', 'w') as f: d = { 'student': { 'name': 'Lily', 'age': 21, 'love': { 'ball': 'volleyball', 'book': 'Python' } }, 'teacher': { 'name': 'Bob', 'age': 20 }, 'data': [2, 3, 4, 5] } yaml.dump(d, f) # 加载yaml文件 with open('dump.yml', 'r') as f: data = yaml.load(f) print(data)
yaml.dump([data,filehandle])
yaml.dump 将一个Python对象生成为yaml文档。参数一为要转为yaml文档的数据,参数二必须为一个已经打开的文件对象。
这里是将转成的yaml格式保存到文件里,以下是保存到文件里的数据。
yaml.load([filehandle])
yaml.load接收文件句柄,将yml文件中的数据转为Python的数据类型。
{'data': [2, 3, 4, 5], 'student': {'age': 21, 'love': {'ball': 'volleyball', 'book': 'Python'}, 'name': 'Lily'}, 'teacher': {'age': 20, 'name': 'Bob'}}
可以将yaml与ddt联合应用,将yaml作为数据存储,可以将test case写在yaml文件里。
@file_data('test_data2.yml') def test_data_yaml(self,value): print(value) print(type(value))
- 组合使用后,通过yaml的数据来控制case的执行。
- yaml文档的使用,使case维护更加方便快捷。