python.UnitTest框架(用例执行、结果断言、HTML报告)
本文将以下方面,阐述UnitTest框架的初级操作:
UnitTest介绍:
unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。
UnitTest框架的优点
- 能够组织多个用例去执行
- 提供丰富的断言方法
- 提供丰富的日志与测试结果
需要注意的地方
- UnitTesrt框架是python自带库不需要下载,使用时import即可
- 新建一个测试类是需要继承unittest.TestCase类
UnitTest框架使用:
TestCase类中定义的几个特殊方法
- setUp():每个测试方法运行前运行,测试前的初始化工作。
- tearDown():每个测试方法运行结束后运行,测试后的清理工作。
- setUpClass():所有的测试方法运行前运行,单元测试前期准备,必须使用 @classmethod装饰器进行修饰,setUp()函数之前执行,整个测试过程只执行一次。比如:实例化浏览器、浏览器最大化、隐式等待设置
- tearDownClass():所有的测试方法运行结束后执行,单元测试后期清理,必须使用 @classmethod装饰器进行修饰,tearDown()之后执行,整个测试过程只执行一次。
执行用例
将功能相关的测试用例组合到一起成为一个测试用例集,unittest框架中通过TestSuite类来组装所有的测试用例集。(也就是说,使用测试集合可 以同时执行同一个py文件中的多个测试用例类)
- TestLoader类:测试用例加载器,返回一个测试用例集合
- loadTestsFromTestCase类:根据给定的测试类,获取其中的所有以‘test’开头的测试方法,并返回一个测试集合
- TestSuite类:组装测试用例的实例,支持添加和删除用例,最后将传递给test runner进行测试执行
- TextTestRunner类:测试用例执行类,其中Text 表示以文本形式输出测试结果
测试结果
. (点):执行成功,一个点表示一个测试方法
F:执行失败,如断言失败(输出日志中 failures=1表示一条用例执行失败)
E:用例本身有异常,如除数为零(输出日志中 errors=1表示一条用例异常)
skipped:有几条用例被跳过执行
断言
assertEqual(a, b,[msg = '测试失败时打印的信息']) :断言a和b是否相等,相等则测试用例通过。 assertNotEqual(a, b,[msg = '测试失败时打印的信息']) :断言a和b是否相等,不相等则测试用例通过。 assertTrue(x,[msg = '测试失败时打印的信息']) :断言x是否True,是True则测试用例通过。 assertFalse(x,[msg = '测试失败时打印的信息']) :断言x是否False,是False则测试用例通过。 assertIs(a, b,[msg = '测试失败时打印的信息']) :断言a是否是b,是则测试用例通过。 assertNotIs(a, b,[msg = '测试失败时打印的信息']) :断言a是否是b,不是则测试用例通过。 assertIsNone(x,[msg = '测试失败时打印的信息']) :断言x是否None,是None则测试用例通过。 assertIsNotNone(x,[msg = '测试失败时打印的信息']) :断言x是否None,不是None则测试用例通过。 assertIn(a, b,[msg = '测试失败时打印的信息']) :断言a是否在b中,在b中则测试用例通过。 assertNotIn(a, b,[msg = '测试失败时打印的信息']) :断言a是否在b中,不在b中则测试用例通过。 assertIsInstance(a, b,[msg = '测试失败时打印的信息']) :断言a是是b的一个实例,是则测试用例通过。 assertNotIsInstance(a, b,[msg = '测试失败时打印的信息']) :断言a是是b的一个实例,不是则测试用例通过。
HTML报告
这个模块不能用pip进行安装,只能下载
http://tungwaiyip.info/software/HTMLTestRunner.html
将HTMLTestRunner.py文件复制至Python安装路径下的lib文件夹中
执行 import HTMLTestRunner验证
运用以上所述做个练习:
import os import sys import time import unittest import selenium import HTMLTestRunner # 继承unittest.TestCase类 class NumberTest(unittest.TestCase): def setUp(self): self.a = 10 self.b = 15 # Unittest默认运行以test开头的测试用例 def test_a(self): # 使用unittest.TestCase类下面的断言方法对测试结果的判断 self.assertEqual(self.a+self.b, 10, msg="输入的数字不是10") # @unittest.skip('跳过用例b') def test_b(self): self.assertEqual(self.a-self.b, 20, msg="输入的数字不是20") def test_c(self): self.assertEqual(self.a*self.b, 30, msg="输入的数字不是30") # 在每个测试用例执行完成后都打印"结束" def tearDown(self): print("结束") class LoaderTest(unittest.TestCase): def test_d(self): print("测试LoaderTest") if __name__ == "__main__": # # 执行用例的方法:unittest.main() # # 搜索该模块下所有以test开头的测试用例方法,并按照ASCLL码排序执行用例。 # unittest.main() ''' # 实例化测试套件方法 suite = unittest.TestSuite() # 一次加载多个测试用例并实例化 testlist = [NumberTest("test_a"), NumberTest("test_b")] suite.addTests(testlist) # 一次加载一个测试用例并实例化 # suite.addTest(NumberTest("test_a")) # suite.addTest(NumberTest("test_b")) # 实例化执行测试用例方法 runner = unittest.TextTestRunner() runner.run(suite) ''' # 测试套件运行测试类中的测试方法 ''' # 加载测试用例并实例化 testCase = unittest.TestLoader().loadTestsFromTestCase(NumberTest) testCase01 = unittest.TestLoader().loadTestsFromTestCase(LoaderTest) # 组装被加载的测试用例并实例化 suite = unittest.TestSuite([testCase, testCase01]) # 运行suite unittest.TextTestRunner().run(suite) ''' # 测试套件运行测试类 ''' # 加载测试用例并实例化 testCase = unittest.TestLoader().loadTestsFromTestCase(NumberTest) # 组装被加载的测试用例并实例化 suite1 = unittest.TestSuite([testCase]) # 实例化创建时间 cur_time = time.strftime('%Y-%m-%d_%H_%M_%S') # 实例化HTML文件的信息属性 filename = os.path.dirname(os.path.abspath('.')) + '\\学习笔记\\' + cur_time + '.html' # 实例化打开HTML的文件操作 f = open(filename, "wb") # 实例化生成HTML的操作 runner = HTMLTestRunner.HTMLTestRunner(stream=f, title="测试报告", description='测试报告描述') # 执行用例 runner.run(suite1) ''' # HTML报告