以下是unittest的运行流程,帮助我们理解运行原理,以便于更好的使用它来帮助我们测试,提高测试效率。
详细介绍每一步的作用:
unittest.TextTestRunner()
将结果输出到流的基本测试运行器实现。如果stream 是None
,则将默认值sys.stderr
用作输出流。此类具有一些可配置的参数(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False),参考unittest单元测试框架教程1-运行测试脚本都已经介绍。
TextTestRunner.run(unittest.TestSuite) (unittest.TestCase)
使用unittest.TextTestRunner对象运行unittest.TestSuite对象。此方法采用TestSuite或者
TestCase
实例,并通过调用_makeResult()创建TestResult, 然后运行测试并将结果打印到stdout。
TestLoader.loadTestsFrom*(module)、TestLoader.discover、testmodule(ttestmethod)
这些方法都将返回测试用例对象unittest.TestCase()
addTest(unittest.TestCase)
将TestCase对象加入unittest.TestSuite对象
_makeResult()
生成并初始化unittest.testresult()对象
startTestRun()
在执行任何测试之前调用一次。
默认实现不执行任何操作。
unittest.TestSuite.run(unittest.testresult)
运行与此套件相关的测试,将结果收集到作为result传递的测试结果对象中。请注意,不同于 TestCase.run()
,TestSuite.run()
需要传递结果对象。
_handleClassSetUp()
运行模块中的setupClass方法,没有则跳过
unittest.TestCase.run(unittest.testresult)
运行测试,将结果收集到TestResult
作为result传递的对象中。如果省略result或None
,则将创建一个临时结果对象(通过调用该defaultTestResult()
方法)并将其使用。结果对象返回给run()
的调用者。
通过简单地调用TestCase
实例,可以达到相同的效果。
_Outcome(unittest.testresult)
初始化并记录运行用例是成功与否,并记录错误expecting_failure等信息
setUp()
测试模块中的setUp()方法,相当于对unittest.TestCase.setUp()的重写
testMethod()
测试模块中的测试方法,如test_add1
tearDown()
同setUp()
addSuccess(unittest.TestCase)
在测试用例测试成功时调用。默认实现不执行任何操作,可在模块中对其进行重写。
stopTest(unittest.TestCase)
不管结果如何,在执行完测试用例测试之后调用,可在模块中对其进行重写。
_handleModuleTearDown(unittest.testresult)
运行模块中的teardownClass方法,没有则跳过
stopTestRun()
执行完所有测试后调用一次。默认实现不执行任何操作,可在模块中对其进行重写。
wasSuccessful()
如果所有的测试用例运行通过返回True
,否则返回 False
。
BeautifulReport
第三方测试报告,内容比较详细,推荐使用
知道了大概的运行机制,我们可以尝试使用代码组织测试套件和用例的结构,自定义运行,依然使用测试文件testmath.py
import unittest
from jisuanqi import *
class TestAdd(unittest.TestCase):
def setUp(self):
self.a = 0
self.b = 0
def tearDown(self):
pass
def test_add1(self):
'''测试加法程序'''
self.a = 1
self.b = 1
answer = 2
try:
self.assertEqual(jiafa(self.a, self.b), answer)
print(str(self.a) + '+' + str(self.b) + '=' + str(answer))
except Exception as e:
print(str(self.a) + '+' + str(self.b) + '=' + str(answer) + ' X')
raise e
def test_add2(self):
'''测试加法程序'''
self.a = 'a'
self.b = 1
answer = 'a1'
try:
self.assertEqual(jiafa(self.a, self.b), answer)
print(str(self.a) + '+' + str(self.b) + '=' + str(answer))
except Exception as e:
print(str(self.a) + '+' + str(self.b) + '=' + str(answer) + ' X')
raise e
class TestChengfa(unittest.TestCase):
def setUp(self):
self.a = 0
self.b = 0
def tearDown(self):
pass
def test_chengfa1(self):
'''测试乘法程序'''
self.a = 1
self.b = 1
answer = 1
try:
self.assertEqual(chengfa(self.a, self.b), answer)
print(str(self.a) + '*' + str(self.b) + '=' + str(answer))
except Exception as e:
print(str(self.a) + '*' + str(self.b) + '=' + str(answer) + ' X')
raise e
def test_chengfa2(self):
'''测试乘法程序'''
self.a = 'a'
self.b = 1
answer = 'a'
try:
self.assertEqual(chengfa(self.a, self.b), answer)
print(str(self.a) + '*' + str(self.b) + '=' + str(answer))
except Exception as e:
print(str(self.a) + '*' + str(self.b) + '=' + str(answer) + ' X')
raise e
使用一下代码运行
from testmath import *
runner = unittest.TextTestRunner()
suite = unittest.TestSuite()
suite.addTest(TestAdd('test_add1'))
suite.addTest(TestChengfa('test_chengfa1'))
result = runner.run(suite)
print(result)
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
1+1=2
1*1=1
<unittest.runner.TextTestResult run=2 errors=0 failures=0>
于是最后返回的测试结果对象
也可以获取所有用例运行
import unittest from testmath import TestAdd case = unittest.TestLoader().getTestCaseNames(TestAdd) runner = unittest.TextTestRunner() suite = unittest.TestSuite() for c in case: suite.addTest(TestAdd(c)) result = runner.run(suite) print(result)
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
1+1=2
a+1=a1
<unittest.runner.TextTestResult run=2 errors=0 failures=0>