深入解析unittest工作原理:TestCase、TestSuite、TestRunner全知道
一、unittest工作原理

unittest最核心的有四部分,它们分别是:TestCase,TestSuite,TestRunner,TestFixture
用户自定义的测试case有一个基类,调用run()方法时,会依次调用setUp方法,会执行用例的方法,还会调用tearDown方法。
TestSuite是测试用例集合,能够通过addTest()方法手动添加Test Case,还能够通过TestLoader自动添加Test Case,TestLoader在添加用例时,是没有顺序的。
TestRunner是运行测试用例的驱动类,它能够执行TestCase,它也能够执行TestSuite,在执行后,TestCase会自动管理TESTResult,TestSuite也会自动管理TESTResult。
简单来说,TestFixture就是做一些测试过程中需要准备的东西,比如创建临时的数据库,创建临时的文件,创建临时的目录等,setUp()和setDown()是其中最常用的方法。
首先要写好TestCase,接着由TestLoader将TestCase加载到TestSuite,再由TestTestRunner运行TestSuite,运行结果保存在TextTestReusult中,整个过程集成于unittest.main模块里。
二、例子如下:
创建一个函数集mathfunc.pyc
def add(a,b):
return a+b
def minus(a, b):
return a-b
def multi(a, b):
return a*b
def divide(a, b):
return a/b
接下来是为这些方法写的一个测试:
test_mathfunc.py
# -*- coding: utf-8 -*-
import unittest
from mathfunc import *
定义一个名为TestMathFunc的类,该类继承自unittest.TestCase
def setUp(self):
打印,“在测试前做些事情。准备环境”。
def tearDown(self):
打印,在测试之后做些事情,清理
def test_add(self):
self.assertEqual(3,add(1,2))
我断言,3不等于,将2和2相加的结果。
使用unittest.skip进行跳过,原因是不想运行这个测试用例
def test_minus(self):
自己断言,1等于3减去2的结果。
def test_multi(self):
自己断言,6 等于,调用 multi 函数,传入参数 2 和 3 的结果。
def test_divide(self):
自己断言,2等于,用6除以3的结果。
自己断言,2.5等于,用5除以2的结果。
如果模块是作为主程序运行,那么执行以下代码块:
unittest.main()
执行结果如下:
组织TestSuite
上面的代码演示了编写一个简单测试的方法,接下来讲述控制用例执行顺序的方式。我们需要使用TestCase,添加到TestCaseDE中的case会依照添加顺序执行。
来个例子:
在文件夹中再新建一个文件。test_suite.py
# -*- coding: utf-8 -*-
import unittest
从test_mathfunc中导入TestMathFunc
if __name__ == '__main__':
suite = unittest.TestSuite()
测试列表中包含,名为“test_add”的数学函数测试,名为“test_minus”的数学函数测试,名为“test_divide”的数学函数测试。
suite.addTests(tests)
runner被赋值为unittest.TextTestRunner,其详细程度设置为2 。
runner.run(suite)
执行情况和我们预想的相同,执行了三个case,而且执行顺序是依照我们添加到suite里的顺序来进行的。
将结果输出到文件中
修改test_suite.py
# -*- coding: UTF-8 -*-
import unittest
from test_mathfunc import TestMathFunc
从HTMLTestRunner中导入HTMLTestRunner
if __name__ == '__main__':
suite = unittest.TestSuite()
#使用这种方法可以对测试用例排序
创建一个列表,名为tests ,其中包含TestMathFunc("test_add") ,TestMathFunc("test_minus") ,TestMathFunc("test_divide") 。
#suite.addTests(tests)
#使用TestLoader的方法传入TestCase
suite添加测试,这些测试通过unittest.TestLoader从TestCase(TestMathFunc)加载而来 。
#在同目录下生成txt格式的测试报告
打开名为'UnittestTextReport.txt'的文件,以追加模式写入,将文件对象命名为f ,
创建一个名为runner的对象,该对象是unittest.TextTestRunner类的实例,其参数stream的值为f,参数verbosity的值为2 。
#runner.run(suite)
打开名为'HTMLReport.html'的文件,以写入模式,将文件对象赋值给f
runner等于HTMLTestRunner,其中stream等于f
title = u'测试报告',
描述是,关于测试用例的执行状况,的内容,。
verbosity = 2
)
runner.run(suite)
执行此文件,能看到,在同目录下生成了一个TXT文件,还能把测试结果以html的格式输出到页面上。
执行结果如下:
在网页中打开测试报告:
小结:
unittest是python自带的单元测试框架,它能够用来作为我们自动化测试框架的用例组织执行框架 。
写好TestCase,这是unittest流程的第一步。然后由TestLoader将TestCase加载到TestSuite。接着由TextTestRunner运行TestSuite。运行的结果保存在TextTestResult中。当我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行。或者我们也可以直接通过TextTestRunner来执行用例。
一个class继承unittest.TestCase,那么它就是一个TestCase,其中那些以test开头的方法,在load的时候会被加载成一个真正的TestCase。
verbosity参数能够对执行结果的输出加以控制,0代表简单报告,1代表一般报告,2代表详细报告。
可以向suite中添加case或suite,通过addTest和addTests来实现,也可以使用TestLoader的loadTestsFrom__()方法 。
使用setUp(),可以在用例执行前布置环境,使用tearDown(),可以在用例执行后清理环境,使用setUpClass(),可以在用例执行前布置环境,使用tearDownClass(),可以在用例执行后清理环境。
我们能够借助skip装饰器跳过某个case,我们能够借助skipIf装饰器跳过某个case,我们能够借助skipUnless装饰器跳过某个case,或者运用TestCase.skipTest方法 。
参数中加stream,能将报告输出到文件,可用TextTestRunner输出txt报告,也可用HTMLTestRunner输出html报告。