将 pytest 覆盖率附加到 Gitlab CI 工件中的文件

Append pytest coverage to file in Gitlab CI artifacts

我正在尝试在 gitlab 阶段拆分我的 pytests 以减少 运行 它们花费的时间。但是,我很难获得完整的报道报告。由于我们的数据库设置方式,我无法使用 pytest-xdist 或 pytest-parallel。

Build:
  stage: Build
  script:
    - *setup-build
    - *build
    - touch banana.xml   # where I write the code coverage collected by pytest-cov
    - *push
  artifacts:
    paths:
    - banana.xml
    reports:
      cobertura: banana.xml

Unit Test:
  stage: Test
  script:
    - *setup-build
    - *pull
    - docker-compose run $DOCKER_IMG_NAME pytest -m unit --cov-report xml:banana.xml --cov=app --cov-append;
  needs:
    - Build

Validity Test:
  stage: Test
  script:
    - *setup-build
    - *pull
    - docker-compose run $DOCKER_IMG_NAME pytest -m validity --cov-report xml:banana.xml --cov=app --cov-append;
  needs:
    - Build

在这两个阶段 运行(构建 - 1 个作业,测试 - 2 个作业)之后,我从 Gitlab 下载 banana.xml 文件,但里面什么也没有,尽管作业说Coverage XML written to file banana.xml

在 gitlab 管道阶段拆分标记的测试时,我是否遗漏了如何将总覆盖率写入工件文件的内容?

如果您想合并多个不同作业的覆盖率报告,则必须添加另一个阶段,该阶段将在您的测试后 运行。这是一个对我有用的例子:

# You need to define the Test stage before the Coverage stage
stages:
  - Test
  - Coverage

# Your first test job
unit_test:
  stage: Test
  script:
    - COVERAGE_FILE=.coverage.unit coverage run --rcfile=.coveragerc -m pytest ./unit
  artifacts:
    paths:
      - .coverage.unit

# Your second test job which will run in parallel
validity_test:
  stage: Test
  script:
    - COVERAGE_FILE=.coverage.validity coverage run --rcfile=.coveragerc -m pytest ./validity
  artifacts:
    paths:
      - .coverage.validity

# Your coverage job, which will combine the coverage data from the two tests jobs and generate a report
coverage:
  stage: Coverage
  script:
    - coverage combine --rcfile=.coveragerc
    - coverage report
    - coverage xml -o coverage.xml
  coverage: '/\d+\%\s*$/'
  artifacts:
    reports:
      cobertura: coverage.xml

您还需要在您的存储库中创建一个包含以下内容的 .coveragerc 文件,以指定 coverage.py 需要使用相对文件路径,因为您的测试 运行不同的 gitlab 运行ners,所以他们的完整路径不匹配:

[run]
  relative_files = True
  source =
  ./

注意:在您的情况下,最好直接使用 coverage 命令(因此 coverage run -m pytest 而不是 pytest),因为它提供更多选项,而这正是 pytest 在幕后使用的东西。


您文件中的问题是您从创建一个空文件开始,尝试从中生成报告(由于文件是空的,因此不会生成任何内容),然后将其传递给两个测试作业, 它们都分别用本地覆盖率报告覆盖它,然后从不使用它。

您需要反过来做,如我的示例所示:运行 首先进行测试,然后在稍后阶段获取测试覆盖率数据,并从中生成报告。