13
08

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()方法,运行过程如下图所示。

20190110_150035_991.png


 

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所示。

20190110_150022_057.png

 

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(二)


为了答谢大家对蜗牛学院的支持,蜗牛学院将会定期对大家免费发放干货,敬请关注蜗牛学院的官方微信。


20181009_153045_341.jpg



版权所有,转载本站文章请注明出处:蜗牛学苑, https://www.woniuxy.cn/article/219