如何在多个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":确保scoreFixture在整个测试模块中只创建一次,所有测试用例共享同一个字典对象(可变对象才能在修改后保持状态)。autouse=True:让output_scoreFixture自动执行,无需在测试用例中显式调用;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钩子:在所有测试执行完成后触发,此时可以安全获取修改后的共享变量并输出。
你之前代码的问题分析
- 第一个版本的
scoreFixture是默认的函数级作用域,每个测试用例都会重新创建一个新字典,两个测试的变量完全独立,无法共享状态。 - 第二个版本的
print语句在模块加载阶段就执行了,而测试用例是在模块加载后才运行的,所以打印的是变量的初始值,不是测试修改后的结果。
内容的提问来源于stack exchange,提问作者chikitin
相关产品推荐
相关产品推荐

