一、unittest 基础介绍
unittest 模块提供了一种结构化的方式来编写测试用例。测试用例继承自 unittest.TestCase 类,并通过一系列的测试方法(以 test_ 开头的方法)来组织。
二、测试套件 (TestSuite)
unittest.TestSuite 是一个容器对象,可以容纳多个测试用例,这样就可以批量执行一组测试用例。
创建测试套件
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
class TestNumberMethods(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 2, 3)
def suite():
suite = unittest.TestSuite()
suite.addTest(TestStringMethods('test_upper'))
suite.addTest(TestNumberMethods('test_add'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 2 tests in 0.000s
#
# OK
三、测试加载器 (TestLoader)
unittest.TestLoader 提供了自动发现和加载测试用例的方法。
使用测试加载器自动发现测试
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
class TestNumberMethods(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 2, 3)
if __name__ == '__main__':
loader = unittest.TestLoader()
tests = loader.discover(start_dir='.', pattern='test*.py')
runner = unittest.TextTestRunner()
runner.run(tests)
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 2 tests in 0.000s
#
# OK
四、测试结果处理器 (TextTestResult)
unittest 默认使用 TextTestResult 来处理测试结果。我们可以通过继承 TextTestResult 来定制输出格式。
定制测试结果输出
import unittest
class CustomTestResult(unittest.TextTestResult):
def addSuccess(self, test):
super().addSuccess(test)
print(f"测试成功: {test}")
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
if __name__ == '__main__':
loader = unittest.TestLoader()
tests = loader.loadTestsFromTestCase(TestStringMethods)
runner = unittest.TextTestRunner(resultclass=CustomTestResult)
runner.run(tests)
# 输出:
# 测试成功: <__main__.TestStringMethods testMethod=test_upper>
# .....
# ----------------------------------------------------------------------
# Ran 1 test in 0.000s
#
# OK
五、测试用例的跳过 (skip)
unittest 提供了 skip 和 skipIf 装饰器来跳过某些测试用例。
使用 skip 装饰器跳过测试
import unittest
class TestStringMethods(unittest.TestCase):
@unittest.skip("暂时跳过此测试")
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
if __name__ == '__main__':
unittest.main()
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 1 test in 0.000s
#
# OK
使用 skipIf 装饰器条件性跳过测试
import unittest
class TestStringMethods(unittest.TestCase):
@unittest.skipIf(True, "当条件为真时跳过此测试")
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
if __name__ == '__main__':
unittest.main()
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 1 test in 0.000s
#
# OK
六、测试用例的重试 (retry)
虽然 unittest 本身不支持测试重试,但可以通过装饰器或第三方库来实现。
使用装饰器实现测试重试
import unittest
import time
def retry(max_attempts=3, delay=1):
def decorator(func):
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
if attempts >= max_attempts:
raise
time.sleep(delay)
return wrapper
return decorator
class TestStringMethods(unittest.TestCase):
@retry(max_attempts=3, delay=1)
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
if __name__ == '__main__':
unittest.main()
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 1 test in 0.000s
#
# OK
七、测试用例的顺序 (order)
默认情况下,unittest 会按照定义的顺序执行测试用例,但如果需要改变顺序,可以通过其他方式实现。
改变测试用例的执行顺序
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
def test_isupper(self):
self.assertTrue('FOO'.isupper())
if __name__ == '__main__':
loader = unittest.TestLoader()
loader.sortTestMethodsUsing = lambda _, x, y: -1 if x > y else 1
tests = loader.loadTestsFromTestCase(TestStringMethods)
runner = unittest.TextTestRunner()
runner.run(tests)
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 3 tests in 0.000s
#
# OK
八、测试用例的标签 (tags)
虽然 unittest 本身不直接支持测试用例的标签功能,但可以通过自定义测试加载器来实现。
使用自定义测试加载器添加标签
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
def load_tests(loader, tests, pattern):
suite = unittest.TestSuite()
for test_case in tests:
if hasattr(test_case, '_testMethodName'):
if 'slow' in getattr(test_case, '_testMethodName'):
continue
suite.addTest(test_case)
return suite
if __name__ == '__main__':
loader = unittest.TestLoader()
tests = loader.loadTestsFromTestCase(TestStringMethods)
tests = load_tests(loader, tests, pattern='test*')
runner = unittest.TextTestRunner()
runner.run(tests)
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 2 tests in 0.000s
#
# OK
九、使用 setUpClass 和 tearDownClass
setUpClass 和 tearDownClass 方法会在所有测试方法之前和之后分别被调用一次。
使用 setUpClass 和 tearDownClass
import unittest
class TestStringMethods(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("设置测试环境")
@classmethod
def tearDownClass(cls):
print("清理测试环境")
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
if __name__ == '__main__':
unittest.main()
# 输出:
# 设置测试环境
# .....
# 清理测试环境
# ----------------------------------------------------------------------
# Ran 2 tests in 0.000s
#
# OK
十、使用 assertRaisesRegex 验证异常消息
assertRaisesRegex 用于验证抛出的异常是否包含预期的消息。
使用 assertRaisesRegex
import unittest
class TestStringMethods(unittest.TestCase):
def test_split(self):
s = 'hello world'
with self.assertRaisesRegex(ValueError, "empty separator"):
s.split('')
if __name__ == '__main__':
unittest.main()
# 输出:
# .....
# ----------------------------------------------------------------------
# Ran 1 test in 0.000s
#
# OK
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。