根本原因是工作目录未切换正确或Python包未安装为可导入状态,需通过pip install -e .或设置PYTHONPATH确保模块可导入,并检查__init__.py是否存在。

GitHub Actions里跑pytest总报ModuleNotFoundError
根本原因是工作目录没切对,或者Python包没安装成可导入状态。GitHub Actions默认在仓库根目录执行,但如果你的测试文件在tests/、源码在src/或myproject/下,直接pytest tests/会找不到模块。
实操建议:
- 用
setup.py或pyproject.toml声明包,然后加pip install -e .(开发模式安装),确保import mypackage能成功 - 不依赖
setup.py的话,在pytest前加一步:export PYTHONPATH="${{ github.workspace }}/src:${{ github.workspace }}" - 检查
__init__.py是否漏放——尤其src/结构下,src/mypackage/__init__.py必须存在,否则不算Python包
怎么让pytest只跑改动的测试文件
GitHub Actions本身不自动识别“哪些.py变了”,得靠git diff手动提取。适合PR场景,避免全量跑测浪费资源。
实操建议:
- 在
steps中加一个run步骤,用git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep '.py$'拿到变更的.py路径 - 再用
xargs把路径传给pytest,比如:pytest $(git diff ... | xargs);注意空输入时加|| true防报错 - 更稳的做法是先生成测试文件列表到变量:
TEST_FILES=$(git diff ... | grep -E '^(tests/|src/.*test)' | xargs),再判断${TEST_FILES}是否为空,为空就跑pytest tests/
pytest参数怎么传进GitHub Actions工作流
不能直接写pytest -xvs --tb=short在run里硬编码,要兼顾可读性、复用性和调试便利性。
实操建议:
- 把常用参数提成
env:变量,比如PYTEST_ARGS: "-xvs --tb=short --maxfail=3",然后run: pytest $PYTEST_ARGS ${TEST_FILES:-tests/} - CI环境禁用颜色和进度条,加
--color=no --disable-warnings,否则日志可能乱码或卡住 - 想看覆盖率?加
coverage run -m pytest,再跟coverage report -m;注意coverage要提前pip install coverage
Windows上pytest路径分隔符出问题
在runs-on: windows-latest下,git diff输出的路径是tests est_foo.py(反斜杠),但pytest在Windows上其实能认,真正崩的是你用grep 'tests/'去匹配——正斜杠在Windows路径里不存在,结果啥都抓不到。
实操建议:
- 统一用
git config core.autocrlf input+git config core.quotePath false,减少路径转义干扰 - 匹配路径时别绑死
/或,改用grep -E '(tests|src)/.*.py$' | sed 's/\///g' - 最省事:直接用
find(Windows runner自带):find tests -name "*.py" -o -path "src/*/test_*.py",绕过git diff
GitHub Actions里跑pytest不是配对命令就行,关键在路径上下文、包可见性、平台差异这三块。很多人卡在第一关就放弃,其实是没意识到pip install -e .和PYTHONPATH才是真正的开关。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











