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

Pytest未执行包模块代码求助(基于《笨办法学Python》)

Pytest运行包测试时模块代码执行异常问题

问题情况

正在学习《笨办法学Python》练习46,搭建项目骨架并使用Pytest测试代码时遇到以下问题:

  • 运行整个包的测试时,测试显示通过,但模块代码未按预期重复执行(仅在单独运行test_Dandy2.py时模块代码会完整运行)
  • 尝试在包目录的__init__.py中写入import Dandy2,触发ImportError
  • 怀疑是Windows+PowerShell环境配置问题(此前需修改执行策略才能运行脚本),但测试能通过、单独运行模块正常,不确定是否属于正常行为

项目目录结构

project_1\
  bin\
  docs\
  project1\
    __init__.py
    Dandy2.py
  tests\
    __init__.py
    test_project1.py
    test_Dandy2.py
  setup.py

PowerShell运行输出

(lpthw) PS C:\Users\desou\OneDrive\Desktop\venvs\projects\project_1> python -m pytest -s
============================================== test session starts ===============================================

platform win32 -- Python 3.12.2, pytest-8.0.2, pluggy-1.4.0
rootdir: C:\Users\desou\OneDrive\Desktop\venvs\projects\project_1

collecting ... Hello this is a test program.

You will be tested, how much is 77 + 33?

\> 4

Test complete. You've proved that you lack math skills.

collected 2 items

tests\test_Dandy2.py SETUP!
I RAN!
.TEAR DOWN!

tests\test_project1.py SETUP!
I RAN!
.TEAR DOWN!


=============================================== 2 passed in 2.22s ===============================================

模块代码(Dandy2.py)

print("Hello this is a test program.")
print("You will be tested, how much is 77 + 33?")
x = input("> ")

if x != '110':
   print("Test complete. You've proved that you lack math skills.")
   pass

else:
   print("Test complete. Congratulations, you have a brain.")
   pass

原因分析

  1. 模块代码执行时机问题:从运行输出看,模块的打印内容在collecting阶段已经出现,说明模块在Pytest收集测试用例时被导入,顶层代码已经执行。你觉得“未执行”可能是误解——顶层代码仅在模块导入时运行一次,若测试用例中没有显式调用模块逻辑,不会重复执行。
  2. init.py导入错误:在包内直接写import Dandy2属于绝对导入,Python会从sys.path中查找该模块,而此时包目录未被识别为路径的一部分,需用相对导入from . import Dandy2才能正确导入同包内的模块。
  3. 测试代码逻辑问题:若你的测试用例仅做简单断言、未调用模块中的逻辑,自然不会触发模块代码的再次执行;单独运行test_Dandy2.py时模块代码运行,是因为单独运行时模块被重新导入,顶层代码再次执行。

解决步骤

1. 修正包内导入方式

修改project1/__init__.py的内容为:

from . import Dandy2

这样就能正确导入同目录下的Dandy2模块,避免ImportError。

2. 让测试用例主动触发模块逻辑

由于当前模块代码都是顶层代码,仅在导入时执行。若想在测试过程中多次执行模块逻辑,需将代码封装成函数:
修改Dandy2.py:

def run_test():
    print("Hello this is a test program.")
    print("You will be tested, how much is 77 + 33?")
    x = input("> ")

    if x != '110':
        print("Test complete. You've proved that you lack math skills.")
    else:
        print("Test complete. Congratulations, you have a brain.")

# 单独运行模块时执行
if __name__ == "__main__":
    run_test()

然后在test_Dandy2.py中导入并调用该函数:

from project1 import Dandy2

def test_dandy2():
    # 调用模块中的测试逻辑
    Dandy2.run_test()
    # 可添加断言逻辑验证结果

3. 确保Pytest能正确识别模块

使用python -m pytest命令运行测试时,项目根目录会自动被加入Python的sys.path,因此from project1 import Dandy2这种绝对导入方式是可行的,无需额外配置PATH。

内容的提问来源于stack exchange,提问作者H. Leoni de Souza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:52:03