CircleCI - pytest 找不到测试使用的文件

CircleCI - pytest cannot find files used by tests

我在 CircleCI 部署中使用 tox 运行 测试。我有一个名为 tests 的目录,在这个目录中我有另一个名为 test_files 的目录,其中包含我用于模拟的文件,例如,带有 JSON 数据的文件。在本地我 运行 使用模拟文件成功测试,但在 CircleCI 中,pytest 无法在目录中找到 JSON 文件:FileNotFoundError: [Errno 2] No such file or directory: 'test_files/data.json'

这是我的 tox.ini:

[tox]
envlist = py37,py38,flake8

[testenv]
deps=-r{toxinidir}/requirements.txt
     -r{toxinidir}/test-requirements.txt

commands=
   pytest -v tests

和我的 config.yml:

version: 2
jobs:
  # using tox
  toxify:

      docker:
        - image: python:3.8

      steps:
        - checkout
        - run:
            name: tox build
            command: |
              pip install tox
              tox -q
        - run:
            name: deploy
            command: |
              ./deploy.sh
workflows:
  version: 2
  build_and_release:
    jobs:
      - toxify:
          filters:
            tags:
              only: /^v\d+\.\d+\.\d+$/

测试示例:

from my_package.image import ImageValidator

def test_valid_image():
    image_validator = ImageValidator("test_files/default_image.png")
    assert image_validator.is_valid_image() is True

我用以下方式打开图像:

file_path = glob.glob(os.path.join(os.path.dirname(file_path), '*.png'))[0]
with open(file_path, "rb") as image:
    image_data = image.read()
    ...

我是不是漏掉了什么?

重申评论:如果您在代码中使用相对路径:

def test_valid_image():
    image_validator = ImageValidator("test_files/default_image.png")

路径 test_files/default_image.png 将相对于当前工作目录进行解析,因此如果完整路径为

/root/tests/test_files/default_image.png

仅当您 运行 来自 /root/tests 的测试时才会找到该文件:cd /root/tests; pytest 将起作用,而其他每个工作目录,例如cd /root; pytest tests/ 会失败。这是您的 tox 配置中当前发生的情况:

commands=
   pytest -v tests

在项目根目录中启动 pytest,在 tests 目录中寻找测试,因此 test_files/default_image.png 解析为 project root/test_files/default_image.png 而不是您期望的 project root/tests/test_files/default_image.png .

有很多方法可以避免这种情况。最好是解析相对于某些静态文件的路径,例如调用模块:

def test_valid_image():
    path = os.path.join(__file__, '..', '..', 'test_files', 'default_image.png')
    image_validator = ImageValidator(path)

或者,通过知道 pytest 在其配置中存储项目根目录:

def test_valid_image(request):
    rootdir = request.config.rootdir
    path = os.path.join(rootdir, 'tests', 'test_files', 'default_image.png')
    image_validator = ImageValidator(path)

现在路径将被忽略工作目录并绑定到一个始终具有相同路径的文件; 运行宁 pytest tests/cd tests/; pytest 现在具有相同的效果。

其他方法正在尝试更改工作目录。由于您的测试期望从 tests 目录执行,因此在 tox.ini:

中导航到它
commands=
    cd tests && pytest; cd ..

commands=
    pushd tests; pytest; popd

等等