How to perform pytest coverage differently between CI builds and Local builds

165 views Asked by At

Let's say I have some code that accesses an audio device, such as the code below:

import pyaudio
def play_audio(audio):
    """Play audio array to the default audio device"""
    if pyaudio.PyAudio().get_host_api_info_by_index(0).get('deviceCount') == 0 : # pragma: no cover
        logging.error(NO_DEVICE_ERROR) 
    else : # ci: no cover        
        stream = pyaudio.PyAudio().open(
            format=pyaudio.paFloat32, channels=2, rate=44100, output=True
        )
        stream.write(audio).tobytes()

I'd like to exclude from pytest code coverage lines 4-5 only during local builds (since I have an audio device), and 7-10 only during my CI build (since there is no audio device in the CI environment).

I've tried defining different keywords for skipping coverage in different situations ("pragma" for local, "ci" for continuous integration), but I have not found documentation on how to specify them from the command line.

How would I configure my .coveragerc to skip sections of the code based on the build parameters?

1

There are 1 answers

1
Ned Batchelder On BEST ANSWER

You can expand environment variables in the coverage settings file. You could put this into your .coveragerc:

[report]
exclude_lines =
    nocover-${COVERAGE_SKIP}

Then annotation your code:

def play_audio(audio):
    """Play audio array to the default audio device"""
    if pyaudio.PyAudio().etcetc(0).get('deviceCount') == 0 : # nocover-local
        logging.error(NO_DEVICE_ERROR) 
    else : # nocover-ci
        stream = pyaudio.PyAudio().open(
            format=pyaudio.paFloat32, channels=2, rate=44100, output=True
        )

When you run tests locally, define an environment variable COVERAGE_SKIP=local. When you run tests on CI, define COVERAGE_SKIP=ci.

Of course, the wording of the comments, and the name of the environment variable are up to you.