You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在多个Pytest测试中维护变量并输出结果至控制台或文件?

在Pytest多测试用例中维护共享变量并输出结果

要解决在多个Pytest测试用例间共享变量,并在测试完成后输出结果的问题,核心是让变量在测试用例间保持状态,同时在合适的时机(所有测试完成后)输出结果。以下是两种可行方案:

方案一:模块级Fixture+自动执行的收尾Fixture

通过设置Fixture的作用域为module(或session,适用于跨模块测试),让变量在整个测试模块中只初始化一次,再用一个自动执行的Fixture在所有测试完成后输出结果。

修改后的test_math_operations.py代码:

import pytest
from math_operations import add_numbers

# 模块级Fixture,整个测试模块共享同一个字典
@pytest.fixture(scope="module")
def score():
    return {"score_pos": 0, "score_neg": 0}

def test_add_numbers_positive(score):
    result = add_numbers(2, 3)
    assert result == 5
    score["score_pos"] = 2

def test_add_numbers_negative(score):
    result = add_numbers(-5, 10)
    assert result == 5
    score["score_neg"] = 3

# 自动执行的收尾Fixture,测试完成后输出结果
@pytest.fixture(scope="module", autouse=True)
def output_score(score):
    yield  # 先执行所有测试用例
    # 计算总分并输出到控制台
    total_score = score["score_pos"] + score["score_neg"]
    print(f"\n测试总分: {total_score}")
    print(f"各部分得分: {score}")
    # 将结果写入文件
    with open("test_score_result.txt", "w", encoding="utf-8") as f:
        f.write(f"测试总分: {total_score}\n")
        f.write(f"各部分得分详情: {str(score)}")

关键说明:

  • scope="module":确保score Fixture在整个测试模块中只创建一次,所有测试用例共享同一个字典对象(可变对象才能在修改后保持状态)。
  • autouse=True:让output_score Fixture自动执行,无需在测试用例中显式调用;yield语句会先执行所有测试用例,之后的代码在所有测试完成后运行,此时可以获取修改后的共享变量。
  • 运行时需加-s参数:执行pytest test_math_operations.py -s,否则Pytest会捕获控制台输出,无法看到打印的结果。

方案二:使用Pytest钩子函数输出结果

通过Pytest的pytest_sessionfinish钩子函数,在整个测试会话结束后获取共享变量并输出,适合需要跨多个测试模块共享状态的场景。

步骤1:创建conftest.py(放在测试目录下)

import pytest

# 会话级Fixture,整个测试会话共享同一个变量
@pytest.fixture(scope="session")
def score():
    return {"score_pos": 0, "score_neg": 0}

# 测试会话结束时触发的钩子函数
@pytest.hookimpl(tryfirst=True)
def pytest_sessionfinish(session, exitstatus):
    # 获取共享的score变量
    score = session.config._store.get("score")
    if score:
        total_score = score["score_pos"] + score["score_neg"]
        # 输出到控制台
        print(f"\n测试会话结束,总分: {total_score}")
        print(f"详细得分: {score}")
        # 写入文件
        with open("session_score_result.txt", "w", encoding="utf-8") as f:
            f.write(f"测试总分: {total_score}\n")
            f.write(f"详细得分详情: {str(score)}")

步骤2:测试模块test_math_operations.py代码

import pytest
from math_operations import add_numbers

def test_add_numbers_positive(score):
    result = add_numbers(2, 3)
    assert result == 5
    score["score_pos"] = 2

def test_add_numbers_negative(score):
    result = add_numbers(-5, 10)
    assert result == 5
    score["score_neg"] = 3

关键说明:

  • scope="session":让score变量在整个测试会话中共享,即使有多个测试模块也能共用。
  • pytest_sessionfinish钩子:在所有测试执行完成后触发,此时可以安全获取修改后的共享变量并输出。

你之前代码的问题分析

  1. 第一个版本的score Fixture是默认的函数级作用域,每个测试用例都会重新创建一个新字典,两个测试的变量完全独立,无法共享状态。
  2. 第二个版本的print语句在模块加载阶段就执行了,而测试用例是在模块加载后才运行的,所以打印的是变量的初始值,不是测试修改后的结果。

内容的提问来源于stack exchange,提问作者chikitin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:50:36