当前位置: 首页 > news >正文

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

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

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() 方法实现。

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

http://www.dtcms.com/a/304347.html

相关文章:

  • 操作系统-lecture2(操作系统结构)
  • Unity的GameObject.Instantiate的使用
  • 津发科技带你了解皮肤电信号中的SCL与SCR
  • SuperClaude Framework 使用指南
  • Ubuntu20.04子系统
  • RPG增容2.尝试使用MMC根据游戏难度自定义更改怪物的属性(二)
  • 基于STM32的PD抓包器
  • Vue3 状态管理新选择:Pinia 从入门到实战
  • Item24:若所有参数皆需类型转换,请为此采用non-member函数
  • [leetcode] 组合总和
  • 《林景媚与数据库神谕》
  • 【C++算法】82.BFS解决FloodFill算法_被围绕的区域
  • 驱动(platform)
  • 青少年软件编程图形化Scratch等级考试试卷(三级)2025年6月
  • CentOS Nginx 1.13.9 部署文档
  • Elasticsearch索引设计与性能优化实战指南
  • 使用Y modem协议进行瑞萨RX MCU OTA数据传输
  • vim的`:q!` 与 `ZQ` 笔记250729
  • 数据结构之时间复杂度
  • 【绘制图像轮廓】——图像预处理(OpenCV)
  • 互联网医院系统包含哪些优势?
  • taro+react重新给userInfo赋值后,获取的用户信息还是老用户信息
  • 搭建一个自定义的 React 图标库
  • 设计模式---单例
  • 测试用例的编写:让测试用例的编写条理起来
  • Redis学习09-AOF-混合持久化
  • iPhone 神级功能,3D Touch 回归!!!
  • 对象的创建过程
  • c++-list
  • Python 程序设计讲义(29):字符串的处理方法——大小写转换