pytest初始化清除【pytest】

发布于:2025-07-16 ⋅ 阅读:(17) ⋅ 点赞:(0)

pytest 中的初始化与清理机制详解

在自动化测试中,初始化与清理操作(setup/teardown)扮演着至关重要的角色,能够为测试环境的复用、资源的回收和测试隔离提供基础保障。pytest 支持多种粒度的初始化与清除:模块级、类级、方法级以及目录级(通过 fixture 实现),下面分别进行介绍。


一、模块级初始化与清理

模块级别setupteardown 是在一个 .py 文件中所有测试类和函数执行之前和之后分别运行一次,适用于为整个模块准备公共资源或环境。

示例代码如下:

def setup_module():
    print('\n *** 初始化-模块 ***')

def teardown_module():
    print('\n *** 清除-模块 ***')

class Test_错误密码:
    def test_C001001(self):
        print('\n用例C001001')
        assert 1 == 1

    def test_C001002(self):
        print('\n用例C001002')
        assert 2 == 2

    def test_C001003(self):
        print('\n用例C001003')
        assert 3 == 2

class Test_错误密码2:
    def test_C001021(self):
        print('\n用例C001021')
        assert 1 == 1

    def test_C001022(self):
        print('\n用例C001022')
        assert 2 == 2

执行命令:

python -m pytest cases -s

运行结果显示模块级初始化和清理各执行一次,分别位于所有用例执行之前与之后,说明模块级 setup_moduleteardown_module 仅调用一次,适合用于准备共享数据或环境。


二、类级初始化与清理

类级别setup_classteardown_class 是在某个测试类的所有方法执行前后调用一次,适用于该类内部所有用例共享的资源管理。

示例:

class Test_错误密码:
    @classmethod
    def setup_class(cls):
        print('\n === 初始化-类 ===')

    @classmethod
    def teardown_class(cls):
        print('\n === 清除 - 类 ===')

    def test_C001001(self):
        print('\n用例C001001')
        assert 1 == 1

    def test_C001002(self):
        print('\n用例C001002')
        assert 2 == 2

    def test_C001003(self):
        print('\n用例C001003')
        assert 3 == 2

类级 setupteardown 在类内所有测试方法执行前后分别运行一次,用于初始化类内资源,如数据库连接或文件句柄等。


三、方法级初始化与清理

方法级别setup_methodteardown_method 是在类中每个测试方法执行前后都会调用,适用于方法之间不能共享状态的情况。

示例代码如下:

class Test_错误密码:
    @classmethod
    def setup_class(cls):
        print('\n === 初始化-类 ===')

    @classmethod
    def teardown_class(cls):
        print('\n === 清除 - 类 ===')

    def setup_method(self):
        print('\n --- 初始化-方法 ---')

    def teardown_method(self):
        print('\n --- 清除-方法 ---')

    def test_C001001(self):
        print('\n用例C001001')
        assert 1 == 1

    def test_C001002(self):
        print('\n用例C001002')
        assert 2 == 2

    def test_C001003(self):
        print('\n用例C001003')
        assert 3 == 2

此机制确保每个测试用例的执行都是“独立”的,彼此之间不会影响状态,便于发现依赖或污染问题。


四、目录级初始化与清理(使用 fixture 实现)

在更高的粒度下,pytest 提供了通过 fixture 实现 包或目录级别的 setup/teardown 功能,通常定义在 conftest.py 中。

示例:

# 文件路径: cases/conftest.py
import pytest

@pytest.fixture(scope='package', autouse=True)
def st_emptyEnv():
    print(f'\n#### 初始化-目录甲')
    yield
    print(f'\n#### 清除-目录甲')

解释:

  • scope='package' 指定了初始化作用范围是整个包(即目录);
  • autouse=True 表示不需要在测试用例中显式引用该 fixture,它会自动生效;
  • yield 语句前是初始化代码,yield 后是清理代码。

注意: 当前 pytest 在该机制中存在一个缺陷 —— 清理代码(yield 之后的部分)并不一定会在“该目录下最后一个用例执行完成后”立即调用。也就是说,某些资源可能未及时释放,从而影响其他目录下的测试行为。

该问题已被用户反馈至 pytest 的 GitHub issue 追踪系统,详情可点击查看:Bug Report

因此,在该问题未修复之前,建议暂时避免依赖目录级别的清理机制,尤其是在有状态污染风险的测试场景中。


总结

级别

函数/方法名

调用频次

适用场景

模块级

setup_module / teardown_module

每个模块一次

整体资源初始化,如数据库连接池

类级

setup_class / teardown_class

每个类一次

类内资源初始化,如 API 会话

方法级

setup_method / teardown_method

每个测试函数一次

保证测试之间完全隔离

目录(包)级

@pytest.fixture(scope="package")

整个目录一次

多模块共享资源(当前有 bug,不推荐)


网站公告

今日签到

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