unittest错误重跑与测试用例跳过机制

发布于:2025-08-04 ⋅ 阅读:(13) ⋅ 点赞:(0)

错误重跑与测试用例跳过机制

unittest 框架中,错误重跑机制和测试用例跳过机制是两个重要的功能,它们分别用于处理不稳定测试和选择性执行测试。以下是对这两个机制的详细介绍:

6. 错误重跑机制

错误重跑机制允许在测试用例失败时自动重试,有助于过滤因环境波动导致的偶发失败(Flaky Tests)。unittest 原生不支持重跑,但可以通过以下方式实现

6.1 自定义重试装饰器

通过装饰器为单个测试方法添加重试逻辑:

import unittest

import functools

def retry(tries=3, exceptions=(AssertionError,)):

    """重试装饰器,用于测试方法"""

    def decorator(func):

        @functools.wraps(func)

        def wrapper(self, *args, **kwargs):

            attempt = 0

            while attempt < tries:

                try:

                    return func(self, *args, **kwargs)

                except exceptions as e:

                    attempt += 1

                    if attempt == tries:

                        raise

                    print(f"测试失败,重试 ({attempt}/{tries}): {e}")

        return wrapper

    return decorator

class TestExample(unittest.TestCase):

    @retry(tries=3)  # 失败时重试3次

    def test_flaky(self):

        import random

        self.assertTrue(random.choice([True, False]))  # 模拟不稳定测试

if __name__ == '__main__':

    unittest.main()

6.2 自定义 TestCase 基类

通过继承 unittest.TestCase 并重写 run() 方法,为所有测试用例添加重试逻辑:

import unittest

class RetryTestCase(unittest.TestCase):

    max_retries = 3  # 全局重试次数

    def run(self, result=None):

        retry_count = 0

        success = False

        

        while not success and retry_count <= self.max_retries:

            # 重置结果对象

            if result:

                result._mirrorOutput = False  # 避免重复输出

                

            # 执行测试

            super().run(result)

            

            # 检查是否需要重试

            if result.failures or result.errors:

                retry_count += 1

                print(f"测试失败,重试 ({retry_count}/{self.max_retries})")

                # 清空当前失败记录

                result.failures = []

                result.errors = []

            else:

                success = True

class TestMath(RetryTestCase):

    def test_flaky(self):

        import random

        self.assertEqual(random.randint(1, 10) % 2, 0)  # 50% 概率失败

6.3 使用第三方库(如 XTestRunner)

XTestRunner 提供了更完善的重跑功能,支持生成包含重跑记录的 HTML 报告:

import unittest

from XTestRunner import HTMLTestRunner

class TestExample(unittest.TestCase):

    def test_flaky(self):

        import random

        self.assertTrue(random.choice([True, False]))

if __name__ == '__main__':

    suite = unittest.TestSuite()

    suite.addTest(TestExample("test_flaky"))

    

    with open('report.html', 'wb') as f:

        runner = HTMLTestRunner(

            stream=f,

            title="测试报告",

            rerun=3  # 失败重试3次

        )

        runner.run(suite)

7. Case 跳过机制

unittest 提供了内置的跳过机制,允许根据条件或版本选择性执行测试用例。

7.1 无条件跳过

使用 @unittest.skip(reason) 装饰器直接跳过测试:

import unittest

class TestFeatures(unittest.TestCase):

    @unittest.skip("该功能尚未实现")

    def test_feature_x(self):

        pass  # 此测试会被跳过

    

    def test_feature_y(self):

        self.assertTrue(True)

7.2 条件性跳过

使用 @unittest.skipIf(condition, reason) 或 @unittest.skipUnless(condition, reason)

import unittest

import sys

class TestPlatform(unittest.TestCase):

    @unittest.skipIf(sys.platform != 'linux', "仅在 Linux 上运行")

    def test_linux_feature(self):

        pass

    

    @unittest.skipUnless(sys.version_info >= (3, 8), "需要 Python 3.8+")

    def test_python38_feature(self):

        pass

7.3 动态跳过

在测试方法中使用 self.skipTest(reason) 动态跳过:

import unittest

import requests

class TestAPI(unittest.TestCase):

    def test_external_api(self):

        try:

            response = requests.get("https://api.example.com")

        except requests.ConnectionError:

            self.skipTest("无法连接到外部 API")

        

        self.assertEqual(response.status_code, 200)

7.4 跳过整个测试类

在类定义前添加装饰器:

import unittest

@unittest.skip("模块重构中,暂不执行测试")

class TestLegacyCode(unittest.TestCase):

    def test_case1(self):

        pass  # 整个类的测试都会被跳过

总结

  • 错误重跑机制:用于处理不稳定测试,通过自定义装饰器、基类或第三方库实现。
  • Case 跳过机制:用于选择性执行测试,通过 @skip@skipIf@skipUnless 装饰器或 self.skipTest() 方法实现。

这两种机制结合使用可以显著提高测试效率,减少无效测试的干扰,让测试聚焦于真正需要验证的功能。


网站公告

今日签到

点亮在社区的每一天
去签到