⼀、unittest测试框架
1. 对unittest的认识
● unittest是python中的⼀个标准库(⽆需下载安装,但使⽤时要导⼊)
● unittest的作⽤
○ 开发⼯程师 —— 使⽤unittest编写单元测试的⽤例脚本代码
○ 测试⼯程师 —— 使⽤unittest组织管理⾃动化测试⽤例脚本
2. unittest框架的四个组成部分
● test case —— 测试⽤例
● test fixture —— 测试固件
● test suite —— 测试套件
● test runner —— 测试运⾏器
⼆、使⽤unittest编写测试⽤例脚本
1. 思路
● ⼀个测试点就定义⼀个测试类
○ 测试类必须继承unittest提供的TestCase类
● 测试点下的⼀条⽤例就定义成为测试类下的⼀个测试⽤例⽅法
○ 测试⽤例⽅法的⽅法名必须以全⼩写的 test 开头
○ 测试⽤例⽅法的执⾏顺序是按照⽅法名的字符ascii码值的顺序,升序执⾏。
2. 代码的模板
import unittest
class TestXXX(unittest.TestCase):
"""测试类:对应⼀个测试点"""
def test_aaa(self):
"""测试⽤例⽅法:对应⼀条测试⽤例"""
编写具体测试步骤和判定测试⽤例是否通过的代码
每个测试⽤例⽅法⼀定要断⾔
def test_bbb(self):
"""测试⽤例⽅法:对应⼀条测试⽤例"""
编写具体测试步骤和判定测试⽤例是否通过的代码
每个测试⽤例⽅法⼀定要断⾔
if __name__ == '__main__':
unittest.main(verbosity=1)
3. 断⾔
● 为了简化测试⽤例结果通过与否的判定(代替if、else的各种逻辑判断),unittest设计了⼤量的各种逻辑判定的⽅法,称之为断⾔⽅法,这些⽅法都是定义在TestCase类中的,因为我们的测试类(是继承了TestCase类的)可以直接使⽤self 进⾏调⽤。
● 断⾔⽅法可以指定断⾔失败时的额外提示信息
○ 如果希望断⾔失败时,显式额外⾃定义的错误提示信息
○ 可以调⽤断⾔⽅法时,传⼊这个信息⽂本做参数(往往是放在最后⼀个参数位置上)
○ 如果断⾔成功,是不会显式错误提示信息的。
● 常⽤的断⾔⽅法
○ self.assertEqual(a, b) —— 断⾔a等于b
○ self.assertNotEqual(a, b) —— 断⾔a不等于b
○ self.assertLess(a, b) —— 断⾔a⼩于b
○ self.assertLessEqual(a, b) —— 断⾔a⼩于或等于b
○ self.assertGreater(a, b) —— 断⾔a⼤于b
○ self.assertGreaterEqual(a, b) —— 断⾔a⼤于或等于b
○ self.assertIn(a, b) —— 断⾔a包含在b之中
○ self.assertNotIn(a, b) —— 断⾔a不包含在b之中
○ self.assertTrue(a) —— 断⾔a为真
○ self.assertFalse(a) —— 断⾔a为假
4. 测试⽤例的执⾏
●【⽅式⼀】使⽤PyCharm的测试插件模块(内部封装了unittest),加载执⾏我们写的测试⽤例脚本。
○ PyCharm可以感知我们定义的类继承了unitest提供的TestCase类
○ 最底层还是调⽤unittest框架(python标准库)执⾏测试⽤例
●【⽅式⼆】调⽤unittest的main函数,加载执⾏我们写的测试⽤例脚本
○ 在定义测试类的模块的最底部,调⽤unittest的main函数,加载当前模块中的所有测试⽤例并执⾏。
○ main函数有⼀个控制测试结果的输出的详细程度的参数 verbosity
■ 分为3个档次:0、1(默认值)、2
5. 测试⽤例执⾏结果通过与否的标准
●测试通过
○ ⼀个测试⽤例⽅法执⾏过程中不报错,就被unittest框架算作执⾏通过。
○ unittest测试结果的标识为: . 、ok
● 测试失败
○ ⽤例断⾔失败
■ 我们调⽤断⾔⽅法self.assertXxx ,断⾔的逻辑不成⽴,发⽣AssertionError异常。
■ 断⾔失败的测试结果标识:F 、 FAIL
○ 代码本身错误
■ 我们调⽤断⾔⽅法时,发⽣的⾮断⾔失败的其它异常。
■ 代码本身错误的测试结果标识: E 、 Error
三、测试固件 —— test fixture
1. 对测试固件的理解
● 测试固件是我们可以在测试类中定义的⼏个特殊⽅法。
● 它们会在测试类中的测试⽤例执⾏到特定阶段时,被⾃动执⾏。
● 如果测试类中没有测试⽤例⽅法,测试固件是不会被执⾏的。
● 不是必须在测试类中使⽤测试固件,就算使⽤,也不是必须4个都使⽤。
● 结合UI⾃动化脚本
○ 将⼀个测试类中所有⽤例的共同的前置动作(启动浏览器、打开⻚⾯呀、登录呀)放在setUp中。
○ 将⼀个测试类中所有⽤例的共同的结尾动作(退出浏览器)放在tearDown中。
○ 如果在setUp中创建了驱动对象实例 dr ,请在dr前使⽤self.dr ,后续都⽤ self.dr
2. 四个测试固件⽅法
● setUp —— 如果测试类中定义了setUp⽅法,则该测试类中的每条⽤例执⾏前,都要先执⾏⼀次setUp⽅法中的代码。
● tearDown —— 如果测试类中定义了tearDown⽅法,则该测试类中的每条⽤例执⾏后,都要再执⾏⼀次tearDown⽅法中的代码(⽆论此测试⽤例执⾏过程中是否失败)。
● setUpClass —— 如果测试类中定义了setUpClass⽅法,则该测试类中的第1条⽤例执⾏前,最先执⾏⼀次(也仅执⾏⼀次)setUpClass⽅法中的代码。
● tearDownClass —— 如果测试类中定义了tearDownClass⽅法,则该测试类中的最后1条⽤例执⾏厚,最后再执⾏⼀次(也仅执⾏⼀次)tearDownClass⽅法中的代码。
四、测试运⾏器和测试套件
1. 测试⽤例对象
● 创建⾃定义的测试类的对象实例 —— 测试⽤例对象
t1 = TestUesrRegister("test1_reg_suc")
t2 = TestUploadPhoto("test2_upload_fail_wrong_file_type")
2. 测试运⾏器 —— test runner
● TextTestRunner 类 —— ⽂本测试运⾏器类
● 负责执⾏测试⽤例的
● 创建测试运⾏器对象,调⽤ run ⽅法,执⾏指定的测试⽤例
from unittest import TextTestRunner
r = TextTestRunner(verbosity=1)
r.run(测试⽤例对象|测试套件对象)
3. 测试套件 —— test suite
● TestSuite 类 —— 测试套件类
● 负责将测试⽤例打包的
● 创建测试套件对象,调⽤addTest 或 addTests ⽅法,将测试⽤例对象添加到测试套件⾥。
from unittest import TestSuite
s = TestSuite()
s.addTest(⼀个测试⽤例对象或另⼀个套件)
s.addTests(⼀组测试⽤例对象或另⼀个套件)
4. 测试加载器类 —— TestLoader
● 智能地搜索指定包及其后代包中的测试⽤例,并且创建测试套件,将测试⽤例打包到测试套件中。
● 创建测试加载器对象,调⽤ discover ⽅法:加载指定包及其后代包中、且符合指定⽂件名格式的⽂件中的所有测试⽤例,然后将⽤例添加到测试套件中,最后返回这个装满着测试⽤例的套件对象。
from unittest import TestLoader
# s = TestLoader().discover("包的路径", "⽂件名格式")
# 加载thinksns.testcase包及其后代包中所有以“test”开头、“.py”结尾的⽂件中的测试⽤例s = TestLoader().discover("thinksns.testcase", "test*.py
五、使⽤第3⽅的测试运⾏器 —— ⽣成HTML格式的测试报告
1. 常⻅的第3⽅测试运⾏器,⽣成HTML格式测试报告的
● HTMLTestRunner、BSTestRunner、BeautifulReport、……
2. HTMLTestRunner模块
● ⽼师将HTMLTestRunner.py进⾏了输出的汉化,能够⽣成中⽂的测试报告⽂件。
● 需要将HTMLTestRunner.py拷⻉到项⽬⼯程中,导⼊后即可使⽤。
● 使⽤HTMLTestRunner.py中定义的⼀个测试运⾏器类 —— HTMLTestRunner类
rom xxx.HTMLTestRunner import HTMLTestRunner
with open("xxx.html", "wb") as f:
r = HTMLTestRunner(f, title="测试报告标题", description="测试报告描述")
r.run(测试套件)