GitHub Actions中使用subprocess.call调用pytest执行测试失败
解决GitHub Actions中subprocess调用脚本的ModuleNotFoundError问题
问题场景
在GitHub CI流水线中,通过test.py的subprocess调用./folder/file.py执行测试时,触发如下错误导致测试失败,但本地运行完全正常:
出错的subprocess代码
subprocess.call( args=[ "python", "./folder/file.py", "--file_path", "tests/local_tests/test_data/data.txt", # pylint: disable=line-too-long "--silent", ] )
捕获到的错误信息
----------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
File "./folder/file.py", line 10, in
from folder.aux import function
ModuleNotFoundError: No module named 'folder'
GitHub Actions配置
name: integration_tests_container run-name: ${{ github.actor }}'s integration tests on ES container on: pull_request: branches: [main, dev] types: [opened, reopened] push: paths-ignore: - '**.md' - './docs' - 'Dockerfile' - './.github/workflows/ci-production.yml' - './.github/workflows/evaluate_clustering.yml' - './.github/workflows/build_docs.yml' jobs: run_integration_tests: runs-on: ubuntu-latest strategy: matrix: python-version: [3.8] steps: - name: Setup Python uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Checkout branch uses: actions/checkout@v3 - name: Install requirements run: | pip install -r requirements.txt - name: Launching ES db container run: | cd ./folder_local_db docker compose up -d - name: Execute tests run: | sleep 20 # to avoid connection error python -m pytest ./tests/integration_tests
问题根源
本地运行时,Python解释器默认将当前工作目录加入模块搜索路径(sys.path),所以能识别folder模块。但在GitHub Actions环境中,subprocess启动的独立Python进程,其模块搜索路径可能未包含项目根目录,导致无法找到folder模块。
三种解决办法
1. 以模块形式调用脚本
把直接执行脚本改为通过-m参数以模块方式运行,Python会自动处理模块路径:
subprocess.call( args=[ "python", "-m", "folder.file", "--file_path", "tests/local_tests/test_data/data.txt", "--silent", ] )
这种方式要求项目根目录在Python的sys.path中,CI环境下checkout后默认处于项目根目录,因此该方式有效。
2. 手动设置PYTHONPATH环境变量
可以在subprocess调用时传入PYTHONPATH,或者在CI步骤中全局设置:
- 在代码中设置:
import os import subprocess # 根据test.py的实际位置调整项目根目录的获取方式 project_root = os.path.abspath(os.getcwd()) subprocess.call( args=[ "python", "./folder/file.py", "--file_path", "tests/local_tests/test_data/data.txt", "--silent", ], env={**os.environ, "PYTHONPATH": project_root} )
- 在GitHub Actions中设置:
修改Execute tests步骤:
- name: Execute tests run: | sleep 20 # to avoid connection error PYTHONPATH=$(pwd) python -m pytest ./tests/integration_tests
3. 以可编辑模式安装项目
在CI的依赖安装步骤后,添加项目安装命令,将项目模块加入Python路径:
- name: Install requirements run: | pip install -r requirements.txt pip install -e . # 可编辑模式安装,让Python识别项目模块
内容的提问来源于stack exchange,提问作者An old man in the sea.
相关产品推荐
相关产品推荐

