Unittest 支持跳过单个测试用例方法甚至整个测试类,用于控制测试用例的运行。
Unittest 还可以将测试标记为“预期失败expected failure
”,即本来就应该失败或者随着程序版本的更新已不能正常运行的测试,标记后该用例失败也不会认为是测试结果上的失败,也就是说不会将该用例的失败计入测试结果。
跳过测试
跳过测试有两种方式可以实现,一种是使用 skip() 装饰器,装饰类或者用例,另一种是直接调用 TestCase.skipTest() 。
装饰器有三种:
-
@unittest.skip(reason)
无条件跳过当前装饰的用例或类。reason 参数必填,用于描述跳过用例的理由。
-
@unittest.skipIf(condition, reason)
条件 condition 参数为 True 的时候,跳过用例。reason 用于描述跳过用例的理由。
@unittest.skipUnless(condition, reason)
与 skipIf() 相反。condition 参数为 False 的时候,跳过用例。reason 用于描述跳过用例的理由。
这次为了演示,将前面案例中的 4 个用例放在一个文件中,分别演示三种 skip:
import unittest
from add import add
is_smoke = False
class TestAddOne(unittest.TestCase):
@unittest.skip('直接跳过用例演示!') # => skip
def test_add_int(self):
'''测试int相加'''
result = add(5, 100)
print('整数相加结果:', result)
self.assertEqual(result, 105, '整数相加错误')
@unittest.skipIf(is_smoke, '非冒烟用例,冒烟时不执行') # => skipIf
def test_add_str(self):
'''测试str相加'''
result = add('5', '6')
print('字符串相加结果:', result)
self.assertEqual(result, '56', '字符串相加错误')
class TestAddTwo(unittest.TestCase):
@unittest.skipUnless(is_smoke, '冒烟用例,只在冒烟时执行') # => skipUnless
def test_add_list(self):
result = add(['1', '2'], ['a', 'b'])
print('列表相加结果:', result)
self.assertEqual(result, ['1','2','a','b'], '列表相加错误')
def test_add_tuple(self):
result = add((1,2), (3,4))
print('元组相加结果:', result)
self.assertEqual(result, (1,2,3,4), '元组相加错误')
if __name__ == "__main__":
unittest.main()
当 is_smoke = True
时,会跳过 test_add_int
和 test_add_str
。skip 装饰的 test_add_int
始终会跳过,test_add_str
由 skipIf 装饰,当 is_smoke 为 True 时跳过。
ss..
-------------------------------------
Ran 4 tests in 0.001s
OK (skipped=2)
列表相加结果: ['1', '2', 'a', 'b']
元组相加结果: (1, 2, 3, 4)
s
表示跳过的用例,skipped=2
跳过两个用例。
当 is_smoke = False
时,会跳过 test_add_int
和 test_add_list
。skip 装饰的 test_add_int
始终会跳过,test_add_list
由 skipUnless 装饰当 is_smoke 为 False 时跳过。
s.s.
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK (skipped=2)
字符串相加结果: 56
元组相加结果: (1, 2, 3, 4)
装饰类与装饰用例类似,并且直接跳过整个类中的所有用例:
@unittest.skip('演示跳过装饰类')
class TestAddTwo(unittest.TestCase):
pass
自己试试!
除了使用装饰器跳过外,还可以使用 TestCase.skipTest() 直接在 setUp() 方法或者用例内部跳过。
在 setUp() 中使用会跳过整个测试类。
import unittest
from add import add
is_smoke = True
class TestAddOne(unittest.TestCase):
def setUp(self):
if is_smoke:
self.skipTest('直接跳过演示') # => 直接调用skipTest()
def test_add_int(self):
'''测试int相加'''
result = add(5, 100)
print('整数相加结果:', result)
self.assertEqual(result, 105, '整数相加错误')
def test_add_str(self):
'''测试str相加'''
if is_smoke:
self.skipTest('非冒烟用例,冒烟时不执行') # => 在用例内调用
result = add('5', '6')
print('字符串相加结果:', result)
self.assertEqual(result, '56', '字符串相加错误')
if __name__ == "__main__":
unittest.main()
上面演示了在 setUp() 中使用 skipTest() 跳过整个类,在用例中使用跳过当前用例。
标记预期失败
标记预期失败,用于针对肯定会失败的用例,该用例依然会运行,只是就算未通过也不会计入失败的用例。但是如果该用例运行成功,则会标识用例失败。
我们将 TestAddTwo 中的最后一个用例标记为预期失败:
class TestAddTwo(unittest.TestCase):
@unittest.expectedFailure # => 注意,没有括号
def test_add_tuple(self):
result = add((1,2), (3,4))
print('元组相加结果:', result)
self.assertEqual(result, (1,1,3,4), '元组相加错误')
运行后的结果为:
...x
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK (expected failures=1)
整数相加结果: 105
字符串相加结果: 56
列表相加结果: ['1', '2', 'a', 'b']
元组相加结果: (1, 2, 3, 4)
x
,表示标记预期失败,三个成功,一个预期失败。test_add_tuple
用例结果是故意写成失败的,但是并没有标记为失败,只是标记为 x
。