单元测试unittest提供了四个装饰器,用以实现测试跳过和预期故障。
首先看一段代码:
#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()
跳过测试的方法:
- @unittest.skip(reason):无条件跳过被装饰的测试用例
- @unittest.skipIf(condition,reason):条件为真则跳过测试用例,为假则执行测试
- @unittest.skipUnless(condition,reason):条件为假则跳过测试用例,为真则执行测试
预期故障的方法:
- @unittest.expectedFailure:将测试标记为预期的失败。 如果测试在运行时失败,则测试不会被视为失败
经验浅谈:
使用这几个装饰器时,有一点要注意,条件跳过测试的两个方法(@unittest.skipIf(condition,reason)和@unittest.skipUnless(condition,reason)),条件判断表达式condition中如果用到类变量,该类变量的取值会取最初始赋给它的值,而在测试用例中对它进行改变是无法影响装饰器的取值的。
看下面这段代码:
#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。
加上装饰器后,预期结果是:只有testOne能执行,testTwo被跳过。而实际的结果是:
Finding files... done. Importing test modules ... done. I am testTwo, nice to meet you! ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
testTwo还是被执行了一遍。
经过探索发现,@unittest.skipIf(flag, '条件为真则跳过') 装饰器里的类变量flag实际上的取值是最开始的赋值False,所以判断条件为False,测试用例被执行。相反的,如果flag一开始的赋值是True,然后在执行testOne时,改成False,执行脚本时,testTwo一直被跳过。
所以这里要注意的是,装饰器的条件表达式里的变量取值并不遵循测试用例执行的顺序,可以理解为它的取值先于所有的测试用例并且独立于测试用例,只和类变量的赋值有关。