0

Similar question but unfortunately no clear answer: here

I've been trying to get pytest, which runs during my GitHub Actions CI, to produce a code coverage badge on my readme.md.

My approach was:

  1. Use pytest Source/tests -v --cov to generate a .coverage file at the root.
  2. Use coveragepy-lcov --data_file_path .coverage --output_file_path lcov.info to convert this .coverage file into lcov.info which is also at the root, using this tool
  3. In the main.yml for GitHub actions, add, to the jobs: build: steps: section
      - name: Upload Coverage Results
        uses: coverallsapp/github-action@master
        with:
          github-token: ${{ secrets.github_token }}
          path-to-lcov: lcov.info

The build passed but results in 0% code coverage. I don't know why. Locally my code has ~90% code coverage. You can see the coveralls page for my build here. The repo is here.

In addition to this problem, I also ran into another. When I add the pytest and coveragepy-lcov commands to the main.yml file (see below) then GitHub Actions fails out at the install stage of the coveragepy-lcov library:

Run pip install coveragepy-lcov
Collecting coveragepy-lcov
  Downloading coveragepy_lcov-0.1.2-py3-none-any.whl (7.7 kB)
Requirement already satisfied: coverage>=5.5 in /opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages (from coveragepy-lcov) (7.1.0)
Requirement already satisfied: click>=7.1.2 in /opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages (from coveragepy-lcov) (8.1.3)
Installing collected packages: coveragepy-lcov
Successfully installed coveragepy-lcov-0.1.2
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.10.9/x64/bin/coveragepy-lcov", line 5, in <module>
    from coveragepy_lcov.cli import main
  File "/opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages/coveragepy_lcov/cli.py", line 3, in <module>
    from .converter import Converter
  File "/opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages/coveragepy_lcov/converter.py", line 5, in <module>
    from coverage.files import FnmatchMatcher, prep_patterns
ImportError: cannot import name 'FnmatchMatcher' from 'coverage.files' (/opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages/coverage/files.py)
Error: Process completed with exit code 1.

Please can anyone help with what is going on?

The complete main.yml file which was used on the failing run was:

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10']
    timeout-minutes: 5

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install flake8 pytest pytest-cov coveragepy-lcov

      - name: Lint with flake8
        run: flake8 --statistics

      - name: Run unit tests with pytest and code coverage with coverage.py
        run: pytest Source/tests -v --cov

      - name: Convert Coverage Results
        run: |
          coveragepy-lcov --data_file_path .coverage --output_file_path lcov.info

      - name: Upload Coverage Results
        uses: coverallsapp/github-action@master
        with:
          github-token: ${{ secrets.github_token }}
          path-to-lcov: lcov.info
Nick_2440
  • 75
  • 1
  • 13

2 Answers2

0

By fiddling with the actions commands a bit, I was able to make it work correctly.

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.10']
    timeout-minutes: 5

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install flake8 pytest pytest-cov

      - name: Lint with flake8
        run: flake8 --statistics

      - name: Run unit tests with pytest and code coverage with coverage.py
        run: pytest Source/tests -v --cov=Source/ --cov-report lcov:Source/tests/lcov.info

      - name: Upload Coverage Results
        uses: coverallsapp/github-action@master
        with:
          github-token: ${{ secrets.github_token }}
          path-to-lcov: Source/tests/lcov.info

My file directory structure was

.github/workflows/actions.yml
Source/
    tests/
        ...  # test files ran by pytest here
    ...  # source code here
requirements.txt  # among others in root
Nick_2440
  • 75
  • 1
  • 13
0

I just wanted to add some info that I hope is helpful for next time:

First, when you have a non-empty coverage report but are seeing 0.0% code coverage at Coveralls, it's because, while your Coveralls integration found your coverage report (lcov.info), it could not find the source files mentioned in the report, at the (relative) filepaths given. When the integration checks for the existence of each file in your git tree, and can't find one, it logs its coverage as 0.0%.

There are two solutions for this:

  1. Your solution: rearrange where you're running tests in relation to your git root directory and/or use absolute paths to make sure the integration finds the files; or
  2. Use the base-path input option supplied by the Coveralls Github Action, which is meant to correct for this kind of discrepancy, which is sometimes unavoidable with complex projects (like big monorepos with lots of subprojects).

Last, a suggestion:

You might consider upgrading to the latest version of the Coveralls Github Action (>v2.0) since its underlying integration is Coveralls' Universal Coverage Reporter, which natively supports pytest-cov.

James
  • 66
  • 3