单元测试unittest提供了四个装饰器,用以实现测试跳过和预期故障。less
首先看一段代码:单元测试
#coding=utf-8 import unittest import myLogging class Test(unittest.TestCase): flag = False def setUp(self): pass def tearDown(self): pass @unittest.skip('无条件跳过 testOne') def testOne(self): print("I am testOne, nice to meet you!") @unittest.skipIf(flag, '条件为真则跳过') def testTwo(self): print("I am testTwo, nice to meet you!") @unittest.skipUnless(flag,'条件为假则跳过') def testThree(self): print("I am testThree, nice to meet you!") @unittest.expectedFailure def testFour(self): print("I am testFour, nice to meet you!") @unittest.expectedFailure def testFive(self): ''' This is a test ''' self.assertTrue('True') self.assertIs('True', True) print("I am testFive, nice to meet you!") myLogging.logging.debug("ceshi") if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main()
跳过测试的方法:测试
预期故障的方法:spa
经验浅谈:debug
使用这几个装饰器时,有一点要注意,条件跳过测试的两个方法(@unittest.skipIf(condition,reason)和@unittest.skipUnless(condition,reason)),条件判断表达式condition中若是用到类变量,该类变量的取值会取最初始赋给它的值,而在测试用例中对它进行改变是没法影响装饰器的取值的。code
看下面这段代码:blog
#coding=utf-8 import unittest class Test(unittest.TestCase): flag = False def setUp(self): pass def tearDown(self): pass def testOne(self): Test.flag = True @unittest.skipIf(flag, '条件为真则跳过') def testTwo(self): print("I am testTwo, nice to meet you!") if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main()
这里两个测试用例,不考虑装饰器时,执行顺序是先testOne再testTwo。在testOne中,对类变量flag作了改变,变成True。ip
加上装饰器后,预期结果是:只有testOne能执行,testTwo被跳过。而实际的结果是:utf-8
Finding files... done. Importing test modules ... done. I am testTwo, nice to meet you! ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
testTwo仍是被执行了一遍。it
通过探索发现,@unittest.skipIf(flag, '条件为真则跳过') 装饰器里的类变量flag实际上的取值是最开始的赋值False,因此判断条件为False,测试用例被执行。相反的,若是flag一开始的赋值是True,而后在执行testOne时,改为False,执行脚本时,testTwo一直被跳过。
因此这里要注意的是,装饰器的条件表达式里的变量取值并不遵循测试用例执行的顺序,能够理解为它的取值先于全部的测试用例而且独立于测试用例,只和类变量的赋值有关。