Unittest核心API(一)
作为Unittest框架中最重要的部分,TestCase为所有测试类的父类而被继承。该类提供了驱动测试、丰富的断言、报告失败等功能。下面是使用dir()函数查询出来的结果,可以看到成员数量非常多,下面我们抽取其中最重要也是最常用的部分进行详解。
作为Unittest框架中最重要的部分,TestCase为所有测试类的父类而被继承。该类提供了驱动测试、丰富的断言、报告失败等功能。下面是使用dir()函数查询出来的结果,可以看到成员数量非常多,下面我们抽取其中最重要也是最常用的部分进行详解。
['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_addExpectedFailure', '_addSkip', '_addUnexpectedSuccess', '_baseAssertEqual', '_classSetupFailed', '_deprecate', '_diffThreshold', '_feedErrorsToResult', '_formatMessage', '_getAssertEqualityFunc', '_truncateMessage', 'addCleanup', 'addTypeEqualityFunc', 'assertAlmostEqual', 'assertAlmostEquals', 'assertCountEqual', 'assertDictContainsSubset', 'assertDictEqual', 'assertEqual', 'assertEquals', 'assertFalse', 'assertGreater', 'assertGreaterEqual', 'assertIn', 'assertIs', 'assertIsInstance', 'assertIsNone', 'assertIsNot', 'assertIsNotNone', 'assertLess', 'assertLessEqual', 'assertListEqual', 'assertLogs', 'assertMultiLineEqual', 'assertNotAlmostEqual', 'assertNotAlmostEquals', 'assertNotEqual', 'assertNotEquals', 'assertNotIn', 'assertNotIsInstance', 'assertNotRegex', 'assertNotRegexpMatches', 'assertRaises', 'assertRaisesRegex', 'assertRaisesRegexp', 'assertRegex', 'assertRegexpMatches', 'assertSequenceEqual', 'assertSetEqual', 'assertTrue', 'assertTupleEqual', 'assertWarns', 'assertWarnsRegex', 'assert_', 'countTestCases', 'debug', 'defaultTestResult', 'doCleanups', 'fail', 'failIf', 'failIfAlmostEqual', 'failIfEqual', 'failUnless', 'failUnlessAlmostEqual', 'failUnlessEqual', 'failUnlessRaises', 'failureException', 'id', 'longMessage', 'maxDiff', 'run', 'setUp', 'setUpClass', 'shortDescription', 'skipTest', 'subTest', 'tearDown', 'tearDownClass'] |
从功能角度划分,将TestCase类中的常用方法分为了以下三类。
1.测试执行
这类方法用于控制测试的执行过程,比如在测试之前连接数据库,测试之后清除增加的字段,跳过某个测试用例等。利用这些方法,可以降低测试代码的复杂度,减少耦合性,结构也更加清晰。
setup()与tearDown()。顾名思义,setUp和tearDown分别是安装和卸载的意思。setUp()方法用于初始化工作,比如在执行测试用例之前进行的系统连接、身份认证等。相反tearDown()方法用于测试后的清理工作,比如数据还原、断开连接等。
下面通过一个实例来理解整个过程。
import unittest class TestDemo(unittest.TestCase): def setUp(self): print('####### setup #######') def tearDown(self): print('####### tearDown #######') def test01(self): print('This is test01.') def test02(self): print('This is test02.') def test03(self): print('This is test03.') if __name__ == '__main__': unittest.main() |
本例中为了更直观的展示运行过程,除了unittest外并未引入其他模块,仅用输出语句来代替测试。TestDemo类中共有5个方法,每个方法都只有一句输出,那么结果是否也如我们所料?
####### setup ####### This is test01. ####### tearDown ####### ####### setup ####### This is test02. ####### tearDown ####### ####### setup ####### This is test03. ####### tearDown ####### ... --------------------------------------------------------------------- Ran 3 tests in 0.000s
OK |
总共输出了9条语句,并且可以清晰的看到,在执行每个测试用例前都调用了setUp()方法,在每个测试用例后都调用了tearDown()方法,运行过程如下图所示。

setUpClass()和tearDownClass()。与setUp()和tearDown()方法相比,仅仅多了一个单词Class,那么相应的初始化和清理工作不是针对每一个测试用例,而是针对于整个类。
import unittest class TestDemo(unittest.TestCase): @classmethod def setUpClass(cls): print('####### setup #######') @classmethod def tearDownClass(cls): print('####### tearDown #######') def test01(self): print('This is test01.') def test02(self): print('This is test02.') def test03(self): print('This is test03.') if __name__ == '__main__': unittest.main() |
需要注意的是,在setUpClass()和tearDownClass()方法前需要加上装饰器@classmethod才能正常运行,后面会有专门的章节对装饰器进行讲解。
####### setup ####### This is test01. This is test02. This is test03. ####### tearDown ####### ... --------------------------------------------------------------------- Ran 3 tests in 0.000s OK |
从运行结果看,初始化方法运行后,紧接着运行所有的测试用例,最后运行清理方法。整个过程中,初始化和清理方法均只运行一次,与内部测试方法的个数无关,如图3-2所示。

run(result=None)方法可以帮助运行某个测试用例,与前面的例子所不同的是,该方法提供了参数result来保存测试的结果,主要运用了以下两种方式。
(1)如果为默认值None,会将测试结果保存到后续提到的defaultTestResult()方法中,通俗的说,即直接输出到控制台中。
import unittest class TestDemo(unittest.TestCase): def test01(self): print('This is test01.') if __name__ == '__main__': TestDemo('test01').run() |
This is test01. |
(2)将测试运行的结果保存到unittest.TestResult()实例化的对象中,输出该对象的字典,结果显示出失败、错误、已运行、跳过、运行字符集等详细信息。
import unittest class TestDemo(unittest.TestCase): def test01(self): print('This is test01.') if __name__ == '__main__': r = unittest.TestResult() TestDemo('test01').run(result=r) print(r.__dict__) |
This is test01. {'failfast': False, 'failures': [], 'errors': [], 'testsRun': 1, 'skipped': [], 'expectedFailures': [], 'unexpectedSuccesses': [], 'shouldStop': False, 'buffer': False, 'tb_locals': False, '_stdout_buffer': None, '_stderr_buffer': None, '_original_stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, '_original_stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, '_mirrorOutput': False} |
注:因为本节内容较长,所以特拆解为了两部分,下周将分享“TestCase类中的常用方法分类中的第二点 “断言"、第三点“其他”知识。
小伙伴们敬请期待哟~
下周推送:Unittest核心API(二)