Bird
Raised Fist0
PyTesttesting~8 mins

Excluding code from coverage in PyTest - Framework Patterns

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Framework Mode - Excluding code from coverage
Folder Structure
project-root/
├── src/
│   └── my_module.py
├── tests/
│   ├── test_feature.py
│   └── conftest.py
├── .coveragerc
├── pytest.ini
└── requirements.txt
Test Framework Layers
  • Source Code (src/): Contains the application code to be tested.
  • Tests (tests/): Contains pytest test files and fixtures.
  • Configuration Files: .coveragerc for coverage settings, pytest.ini for pytest options.
  • Utilities: Helpers or fixtures in conftest.py to support tests.
Configuration Patterns

To exclude code from coverage reports in pytest, use the .coveragerc file with coverage.py settings.

Example .coveragerc content:

[run]
omit =
    src/excluded_module.py
    src/*_deprecated.py

[report]
exclude_lines =
    # Exclude lines with this comment
    pragma: no cover
    if __name__ == '__main__':

In your source code, mark lines or blocks to exclude with # pragma: no cover comment.

Example in my_module.py:

def helper_function():
    # This function is only for debugging
    print("Debug info")  # pragma: no cover

Run tests with coverage using:

pytest --cov=src
Test Reporting and CI/CD Integration
  • Use pytest-cov plugin to generate coverage reports.
  • Configure coverage to exclude unwanted code to keep reports clean and meaningful.
  • Integrate coverage reports in CI pipelines (GitHub Actions, Jenkins, GitLab CI) to fail builds if coverage drops below thresholds.
  • Example GitHub Actions snippet to run tests and upload coverage report:
  • name: Python Tests
    
    on: [push, pull_request]
    
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - name: Set up Python
            uses: actions/setup-python@v4
            with:
              python-version: '3.12'
          - name: Install dependencies
            run: |
              python -m pip install --upgrade pip
              pip install pytest pytest-cov
          - name: Run tests with coverage
            run: pytest --cov=src --cov-report=xml
          - name: Upload coverage to Codecov
            uses: codecov/codecov-action@v3
    
Best Practices
  1. Use # pragma: no cover comments to exclude specific lines or blocks that are not relevant for coverage (e.g., debug prints, platform-specific code).
  2. Configure .coveragerc to omit entire files or folders that should not be counted in coverage (e.g., legacy code, generated files).
  3. Keep coverage reports meaningful by excluding test helpers, mocks, or code that cannot be tested.
  4. Integrate coverage checks in CI to maintain code quality and prevent coverage regression.
  5. Document exclusions clearly so team members understand why some code is excluded.
Self Check

Where in this framework structure would you add a new file to exclude from coverage reporting?

Key Result
Use .coveragerc and pragma comments to exclude code from coverage in pytest frameworks.

Practice

(1/5)
1. What is the purpose of adding # pragma: no cover in your Python test code when using pytest and coverage.py?
easy
A. To exclude specific lines from the coverage report
B. To mark lines that must always be covered by tests
C. To enable debugging mode in pytest
D. To automatically generate test cases for those lines

Solution

  1. Step 1: Understand coverage exclusion

    The comment # pragma: no cover tells coverage.py to ignore that line when measuring test coverage.
  2. Step 2: Purpose in test reports

    This helps keep coverage reports focused on meaningful code, excluding lines like debug prints or platform-specific code.
  3. Final Answer:

    To exclude specific lines from the coverage report -> Option A
  4. Quick Check:

    Exclude lines = D [OK]
Hint: Use '# pragma: no cover' to skip lines in coverage report [OK]
Common Mistakes:
  • Thinking it marks lines to always test
  • Confusing it with pytest debug flags
  • Assuming it generates tests automatically
2. Which of the following is the correct way to exclude a single line from coverage in a Python file using pytest and coverage.py?
easy
A. print('Debug info') # exclude coverage
B. print('Debug info') # no cover pragma
C. print('Debug info') # pragma: no cover
D. print('Debug info') # skip coverage

Solution

  1. Step 1: Identify correct pragma syntax

    The correct syntax to exclude a line is # pragma: no cover exactly as written.
  2. Step 2: Match options to syntax

    Only print('Debug info') # pragma: no cover uses the exact correct comment syntax recognized by coverage.py.
  3. Final Answer:

    print('Debug info') # pragma: no cover -> Option C
  4. Quick Check:

    Exact pragma syntax = A [OK]
Hint: Remember exact comment: '# pragma: no cover' [OK]
Common Mistakes:
  • Swapping words in the pragma comment
  • Using incorrect comment keywords
  • Missing 'pragma:' keyword
3. Consider this Python code snippet tested with pytest and coverage.py:
def func(x):
    if x > 0:
        return x
    else:
        return -x  # pragma: no cover
What will coverage.py report about the line with return -x if it is never executed?
medium
A. The line will be counted as uncovered and reduce coverage percentage
B. The line will be ignored and not affect coverage percentage
C. The test will fail due to missing coverage
D. Coverage.py will raise a syntax error

Solution

  1. Step 1: Understand pragma effect on coverage

    The comment # pragma: no cover tells coverage.py to ignore that line regardless of execution.
  2. Step 2: Effect on coverage report

    Since the line is ignored, not executing it does not reduce coverage percentage.
  3. Final Answer:

    The line will be ignored and not affect coverage percentage -> Option B
  4. Quick Check:

    Pragma ignores line in coverage = B [OK]
Hint: Lines with '# pragma: no cover' don't lower coverage [OK]
Common Mistakes:
  • Assuming ignored lines count as uncovered
  • Expecting test failure due to coverage
  • Thinking pragma causes syntax errors
4. You wrote this code:
def example():
    print('Start')  # pragma no cover
    print('End')
But coverage.py still counts the first print line as uncovered. What is the likely problem?
medium
A. You must disable coverage for the whole file, not single lines
B. Coverage.py does not support excluding print statements
C. The comment must be placed on the line before the code
D. The pragma comment is missing the colon after 'pragma:'

Solution

  1. Step 1: Check pragma syntax

    The correct syntax requires a colon: # pragma: no cover. Missing colon causes coverage.py to ignore the comment.
  2. Step 2: Effect of incorrect syntax

    Without the colon, coverage.py treats the line normally and counts it as uncovered if not executed.
  3. Final Answer:

    The pragma comment is missing the colon after 'pragma:' -> Option D
  4. Quick Check:

    Colon required in pragma comment = A [OK]
Hint: Always include colon: '# pragma: no cover' [OK]
Common Mistakes:
  • Omitting colon after 'pragma:'
  • Placing comment on wrong line
  • Thinking coverage can't exclude print statements
5. You want to exclude a block of code from coverage in a pytest project, but # pragma: no cover only works line-by-line. Which approach correctly excludes multiple lines without affecting other code?
hard
A. Add # pragma: no cover comment to each line in the block
B. Wrap the block in a function and exclude the whole function with a decorator
C. Use if False: around the block to skip it and exclude it from coverage
D. Add # pragma: no cover only on the first and last lines of the block

Solution

  1. Step 1: Understand line-by-line exclusion

    The # pragma: no cover comment excludes coverage only for the line it is on, so each line must have it to be excluded.
  2. Step 2: Evaluate other options

    Wrapping in a function or using if False: changes code behavior or testability; partial comments on first and last lines do not exclude intermediate lines.
  3. Final Answer:

    Add '# pragma: no cover' comment to each line in the block -> Option A
  4. Quick Check:

    Exclude multiple lines by commenting each line = C [OK]
Hint: Comment each line with '# pragma: no cover' to exclude block [OK]
Common Mistakes:
  • Assuming one comment excludes multiple lines
  • Using 'if False:' which affects runtime
  • Trying to exclude with decorators without support