本文共 5356 字,大约阅读时间需要 17 分钟。
测试套件允许你将多个测试用例组合在一起,并灵活控制它们的执行顺序。这对于组织和管理测试用例非常有用。
import unittestclass TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('Foo'.isupper()) import unittestfrom unittest import TestSuite, TextTestRunnersuite = TestSuite()suite.addTest(TestStringMethods('test_upper'))suite.addTest(TestStringMethods('test_isupper'))runner = TextTestRunner()runner.run(suite) unittest 提供了一些装饰器来控制测试行为,比如 skip 和 expectedFailure。
import unittestclass TestDecorators(unittest.TestCase): @unittest.skip("demonstrating skipping") def test_nothing(self): self.fail("shouldn't happen") @unittest.expectedFailure def test_fail(self): self.assertEqual(1, 0, "broken") 通过参数化库,你可以为同一个测试方法提供多种输入,从而减少重复代码。
import unittestfrom parameterized import parameterized@parameterized.expand([ (2, 3, 5), (7, 6, 13), (-1, 1, 0)])def test_add(self, a, b, expected): self.assertEqual(a + b, expected)
虽然 unittest 不直接支持嵌套测试,但你可以通过子类化来实现类似的功能。
import unittestclass TestSub(unittest.TestCase): def test_subtest(self): self.assertEqual(1 + 1, 2)class TestNested(unittest.TestCase): def test_nested(self): suite = unittest.TestLoader().loadTestsFromTestCase(TestSub) result = TextTestRunner(verbosity=2).run(suite) self.assertTrue(result.wasSuccessful())
你可以动态创建测试用例,这在依赖外部数据源时非常有用。
import unittestdef load_tests(loader, tests, pattern): suite = TestSuite() for i in range(1, 4): suite.addTest(MyTest('test_method', i)) return suiteclass MyTest(unittest.TestCase): def __init__(self, methodName, data): super().__init__(methodName) self.data = data def test_method(self): self.assertEqual(self.data % 2, 0) unittest 提供了多种测试加载器,用于自动发现和加载测试用例。
import unittestclass TestLoaders(unittest.TestCase): def test_one(self): self.assertEqual(1 + 1, 2)
unittest 提供了 assertRaises 方法,用于检查函数是否抛出预期的异常。
import unittestclass TestExceptions(unittest.TestCase): def test_divide_by_zero(self): with self.assertRaises(ZeroDivisionError): 1 / 0
子测试允许你在一个测试方法中执行多个断言,并确保所有断言都完成即使其中一个失败。
import unittestclass TestSubtests(unittest.TestCase): def test_subtest(self): for value in [2, 4, 6]: with self.subTest(i=value): self.assertEqual(value % 2, 0)
unittest 提供了 setUp 和 tearDown 方法,用于在每个测试方法前后执行初始化和清理操作。
import unittestimport tempfileclass TestFileOperations(unittest.TestCase): @classmethod def setUpClass(cls): cls.temp_dir = tempfile.TemporaryDirectory() @classmethod def tearDownClass(cls): cls.temp_dir.cleanup() def setUp(self): self.filename = os.path.join(self.temp_dir.name, 'testfile.txt') with open(self.filename, 'w') as f: f.write('Hello, World!') def tearDown(self): try: os.remove(self.filename) except OSError: pass def test_file_content(self): with open(self.filename, 'r') as f: content = f.read() self.assertEqual(content, 'Hello, World!') unittest 提供了强大的断言方法,支持 assertEqual、assertTrue、assertFalse 等。
import unittestclass TestAsserts(unittest.TestCase): def test_assert_equal(self): self.assertEqual(1 + 1, 2) def test_assert_true(self): self.assertTrue(1 == 1) def test_assert_false(self): self.assertFalse(1 == 2) def test_assert_in(self): self.assertIn('a', 'abc') def test_assert_not_in(self): self.assertNotIn('z', 'abc') unittest 提供了 skipIf 和 skipUnless 装饰器,允许根据条件跳过测试。
import unittestimport sysclass TestSkipConditions(unittest.TestCase): @unittest.skipIf(sys.version_info < (3, 8), "requires Python 3.8 or higher") def test_python_version(self): self.assertGreaterEqual(sys.version_info, (3, 8))
unittest 的 capture_output 上下文管理器可以帮助你捕获测试过程中的标准输出和错误。
import unittestfrom io import StringIOclass TestOutputCapture(unittest.TestCase): def test_captured_output(self): with self.captureOutput() as (out, err): print("This is a test message.") self.assertIn("This is a test message.", out) 对于异步代码,可以使用 unittest.IsolatedAsyncioTestCase 来编写异步测试。
import asyncioimport unittestclass TestAsyncMethods(unittest.IsolatedAsyncioTestCase): async def test_async_method(self): result = await self.async_method() self.assertEqual(result, 'expected_result') async def async_method(self): await asyncio.sleep(0.1) return 'expected_result'
你可以扩展 unittest.TestCase 来定义自己的断言方法。
import unittestclass CustomAsserts(unittest.TestCase): def assertIsNone(self, obj, msg=None): if obj is not None: standardMsg = '%s is not None' % str(obj) self.fail(self._formatMessage(msg, standardMsg)) def test_custom_assertion(self): self.assertIsNone(None)
以上内容涵盖了 Python 中常用的测试技巧和工具,包括测试套件、装饰器、参数化测试、嵌套测试、动态生成测试、测试加载器、异常捕获、子测试、设置和清理、断言方法、忽略测试、捕获输出、异步测试和自定义断言等。如果你对某一部分感兴趣,可以深入探索!
转载地址:http://nrafk.baihongyu.com/