Unittest Framework 简明教程
UnitTest Framework - API
本章讨论 unittest 模块中定义的类和方法。此模块中有五个主要类。
This chapter discusses the classes and methods defined in the unittest module. There are five major classes in this module.
TestCase Class
此类的对象表示最小的可测试单元。它包含测试例程,并提供挂钩以便准备各个例程和清理之后的内容。
Object of this class represents the smallest testable unit. It holds the test routines and provides hooks for preparing each routine and for cleaning up thereafter.
TestCase 类中定义了以下方法 −
The following methods are defined in the TestCase class −
Sr.No. |
Method & Description |
1 |
setUp() Method called to prepare the test fixture. This is called immediately before calling the test method |
2 |
tearDown() Method called immediately after the test method has been called and the result recorded. This is called even if the test method raised an exception, |
3 |
setUpClass() A class method called before tests in an individual class run. |
4 |
tearDownClass() A class method called after tests in an individual class have run. |
5 |
run(result = None) Run the test, collecting the result into the test result object passed as result. |
6 |
skipTest(reason) Calling this during a test method or setUp() skips the current test. |
7 |
debug() Run the test without collecting the result. |
8 |
shortDescription() Returns a one-line description of the test. |
Fixtures
一个 TestCase 类内可以编写很多测试。这些测试方法可能需要数据库连接、临时文件或其他资源初始化。这些称为固定装置。TestCase 包含一个特殊钩子来配置和清理你的测试所需的任何固定装置。要配置固定装置,请覆盖 setUp()。要清理,请覆盖 tearDown()。
There can be numerous tests written inside a TestCase class. These test methods may need database connection, temporary files or other resources to be initialized. These are called fixtures. TestCase includes a special hook to configure and clean up any fixtures needed by your tests. To configure the fixtures, override setUp(). To clean up, override tearDown().
在下面的示例中,在 TestCase 类内编写了两个测试。它们测试两个值相加和相减的结果。setup() 方法基于每个测试的 shortDescription() 初始化参数。teardown() 方法将在每个测试的末尾执行。
In the following example, two tests are written inside the TestCase class. They test result of addition and subtraction of two values. The setup() method initializes the arguments based on shortDescription() of each test. teardown() method will be executed at the end of each test.
import unittest
class simpleTest2(unittest.TestCase):
def setUp(self):
self.a = 10
self.b = 20
name = self.shortDescription()
if name == "Add":
self.a = 10
self.b = 20
print name, self.a, self.b
if name == "sub":
self.a = 50
self.b = 60
print name, self.a, self.b
def tearDown(self):
print '\nend of test',self.shortDescription()
def testadd(self):
"""Add"""
result = self.a+self.b
self.assertTrue(result == 100)
def testsub(self):
"""sub"""
result = self.a-self.b
self.assertTrue(result == -10)
if __name__ == '__main__':
unittest.main()
从命令行运行以上代码。它给出以下输出 −
Run the above code from the command line. It gives the following output −
C:\Python27>python test2.py
Add 10 20
F
end of test Add
sub 50 60
end of test sub
.
================================================================
FAIL: testadd (__main__.simpleTest2)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
File "test2.py", line 21, in testadd
self.assertTrue(result == 100)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 2 tests in 0.015s
FAILED (failures = 1)
Class Fixture
TestCase 类有一个 setUpClass() 方法,可以在 TestCase 类内个体测试执行之前覆盖执行。类似地,tearDownClass() 方法将在类中的所有测试之后执行。这两个方法都是类方法。因此,它们必须用 @classmethod 指令装饰。
TestCase class has a setUpClass() method which can be overridden to execute before the execution of individual tests inside a TestCase class. Similarly, tearDownClass() method will be executed after all test in the class. Both the methods are class methods. Hence, they must be decorated with @classmethod directive.
下面的示例演示了这些类方法的使用 −
The following example demonstrates the use of these class methods −
import unittest
class TestFixtures(unittest.TestCase):
@classmethod
def setUpClass(cls):
print 'called once before any tests in class'
@classmethod
def tearDownClass(cls):
print '\ncalled once after all tests in class'
def setUp(self):
self.a = 10
self.b = 20
name = self.shortDescription()
print '\n',name
def tearDown(self):
print '\nend of test',self.shortDescription()
def test1(self):
"""One"""
result = self.a+self.b
self.assertTrue(True)
def test2(self):
"""Two"""
result = self.a-self.b
self.assertTrue(False)
if __name__ == '__main__':
unittest.main()
TestSuite Class
Python 的测试框架提供了一种很有用的机制,根据测试用例实例测试的功能对它们进行分组。此机制由 unittest 模块中的 TestSuite 类提供。
Python’s testing framework provides a useful mechanism by which test case instances can be grouped together according to the features they test. This mechanism is made available by TestSuite class in unittest module.
创建和运行测试套件包括以下步骤。
The following steps are involved in creating and running a test suite.
Step 1 − 创建 TestSuite 类的实例。
Step 1 − Create an instance of TestSuite class.
suite = unittest.TestSuite()
Step 2 − 在套件内添加 TestCase 类中的测试。
Step 2 − Add tests inside a TestCase class in the suite.
suite.addTest(testcase class)
Step 3 − 你还可以使用 makeSuite() 方法从一个类添加测试
Step 3 − You can also use makeSuite() method to add tests from a class
suite = unittest.makeSuite(test case class)
Step 4 − 个体测试也可以添加到套件中。
Step 4 − Individual tests can also be added in the suite.
suite.addTest(testcaseclass(""testmethod")
Step 5 − 创建 TestTestRunner 类的对象。
Step 5 − Create an object of the TestTestRunner class.
runner = unittest.TextTestRunner()
Step 6 − 调用 run() 方法运行套件中的所有测试,将结果收集到测试结果对象中
Step 6 − Call the run() method to run all the tests in the suite
runner.run (suite)
TestSuite 类中定义了以下方法 −
The following methods are defined in TestSuite class −
Sr.No. |
Method & Description |
1 |
addTest() Adds a test method in the test suite. |
2 |
addTests() Adds tests from multiple TestCase classes. |
3 |
run() Runs the tests associated with this suite, collecting the result into the test result object |
4 |
debug() Runs the tests associated with this suite without collecting the result. |
5 |
countTestCases() Returns the number of tests represented by this test object |
下面的示例说明了如何使用 TestSuite 类:
The following example shows how to use TestSuite class −
import unittest
class suiteTest(unittest.TestCase):
def setUp(self):
self.a = 10
self.b = 20
def testadd(self):
"""Add"""
result = self.a+self.b
self.assertTrue(result == 100)
def testsub(self):
"""sub"""
result = self.a-self.b
self.assertTrue(result == -10)
def suite():
suite = unittest.TestSuite()
## suite.addTest (simpleTest3("testadd"))
## suite.addTest (simpleTest3("testsub"))
suite.addTest(unittest.makeSuite(simpleTest3))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
test_suite = suite()
runner.run (test_suite)
可以使用 addTest() 方法,通过取消对包含 makeSuite() 方法的行和注释语句的注释来进行实验。
You can experiment with the addTest() method by uncommenting the lines and comment statement having makeSuite() method.
TestLoader Class
unittest 包具有 TestLoader 类,用于根据类和模块创建测试套件。默认情况下,在调用 unittest.main(0 方法时自动创建 unittest.defaultTestLoader 实例。但是,显式实例可以自定义某些属性。
The unittest package has the TestLoader class which is used to create test suites from classes and modules. By default, the unittest.defaultTestLoader instance is automatically created when the unittest.main(0 method is called. An explicit instance, however enables the customization of certain properties.
在以下代码中,使用 TestLoader 对象将来自两个类的测试收集到一个列表中。
In the following code, tests from two classes are collected in a List by using the TestLoader object.
import unittest
testList = [Test1, Test2]
testLoad = unittest.TestLoader()
TestList = []
for testCase in testList:
testSuite = testLoad.loadTestsFromTestCase(testCase)
TestList.append(testSuite)
newSuite = unittest.TestSuite(TestList)
runner = unittest.TextTestRunner()
runner.run(newSuite)
下表列出 TestLoader 类中的方法列表:
The following table shows a list of methods in the TestLoader class −
Sr.No |
Method & Description |
1 |
loadTestsFromTestCase() Return a suite of all tests cases contained in a TestCase class |
2 |
loadTestsFromModule() Return a suite of all tests cases contained in the given module. |
3 |
loadTestsFromName() Return a suite of all tests cases given a string specifier. |
4 |
discover() Find all the test modules by recursing into subdirectories from the specified start directory, and return a TestSuite object |
TestResult Class
此类用于编译有关已成功测试和已失败测试的信息。TestResult 对象存储一组测试的结果。TestResult 实例由 TestRunner.run() 方法返回。
This class is used to compile information about the tests that have been successful and the tests that have met failure. A TestResult object stores the results of a set of tests. A TestResult instance is returned by the TestRunner.run() method.
TestResult 实例具有以下属性:
TestResult instances have the following attributes −
Sr.No. |
Attribute & Description |
1 |
Errors A list containing 2-tuples of TestCase instances and strings holding formatted tracebacks. Each tuple represents a test which raised an unexpected exception. |
2 |
Failures A list containing 2-tuples of TestCase instances and strings holding formatted tracebacks. Each tuple represents a test where a failure was explicitly signalled using the TestCase.assert*() methods. |
3 |
Skipped A list containing 2-tuples of TestCase instances and strings holding the reason for skipping the test. |
4 |
wasSuccessful() Return True if all tests run so far have passed, otherwise returns False. |
5 |
stop() This method can be called to signal that the set of tests being run should be aborted. |
6 |
startTestRun() Called once before any tests are executed. |
7 |
stopTestRun() Called once after all tests are executed. |
8 |
testsRun The total number of tests run so far. |
9 |
Buffer If set to true, sys.stdout and sys.stderr will be buffered in between startTest() and stopTest() being called. |
以下代码执行了一个测试套件 −
The following code executes a test suite −
if __name__ == '__main__':
runner = unittest.TextTestRunner()
test_suite = suite()
result = runner.run (test_suite)
print "---- START OF TEST RESULTS"
print result
print "result::errors"
print result.errors
print "result::failures"
print result.failures
print "result::skipped"
print result.skipped
print "result::successful"
print result.wasSuccessful()
print "result::test-run"
print result.testsRun
print "---- END OF TEST RESULTS"
代码执行后显示以下输出 −
The code when executed displays the following output −
---- START OF TEST RESULTS
<unittest.runner.TextTestResult run = 2 errors = 0 failures = 1>
result::errors
[]
result::failures
[(<__main__.suiteTest testMethod = testadd>, 'Traceback (most recent call last):\n
File "test3.py", line 10, in testadd\n
self.assertTrue(result == 100)\nAssert
ionError: False is not true\n')]
result::skipped
[]
result::successful
False
result::test-run
2
---- END OF TEST RESULTS