我在 GitHub 中有一个 CI 管道。
在
test.py
文件中,我有以下内容:
subprocess.call(
args=[
"python",
"./folder/file.py",
"--file_path",
"tests/local_tests/test_data/data.txt", # pylint: disable=line-too-long
"--silent",
]
)
使用
pytest
运行它会给出:
----------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
File "./folder/file.py", line 10, in <module>
from folder.aux import function
ModuleNotFoundError: No module named 'folder'
这又导致测试因另一个异常而失败。 当我在本地运行测试时,一切都很顺利。
编辑:
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
我知道有点晚了,但这是您问题的可能原因。 来自文档https://docs.python.org/3/library/subprocess.html#subprocess.run:
解析可执行文件的路径(或args的第一项)是 平台依赖。对于 POSIX,请参阅 os.execvpe(),并注意当 解析或搜索可执行路径,cwd 会覆盖 当前工作目录和env可以覆盖PATH环境 变量。
问题在于覆盖 PYTHONPATH 变量。 本地计算机上的 env 变量与远程 CI 环境上的 env 变量具有不同的 PYTHONPATH。 由于提供的 PYTHONPATH 是 '' 或本地计算机上的 PYTHONPATH,因此导入失败。
要解决此问题,您需要在 github 的 CI 上下文中使用 subprocess 模块时,在调用 subprocess 时为 PYTHONPATH 添加正确的值。
例如这样的事情:
def enforce_env_pythonpath(command):
current_env = os.environ.copy()
process = subprocess.run(command, capture_output=True, text=True,
env=current_env)
然后每当您想要执行任何 subprocess.run 调用时就调用此函数。 请注意,此解决方案不需要额外的参数 capture_output 和 text。以防万一您需要输出并且它不应该是二进制的。