Coverage report formats (terminal, HTML, XML) in PyTest - Build an Automation Script
Start learning this pattern below
Jump into concepts and practice - no test required
import subprocess import os import xml.etree.ElementTree as ET from pathlib import Path def test_coverage_reports(): package_name = "your_package" # Replace with your actual package name # Run pytest with coverage and terminal report result = subprocess.run( ["pytest", f"--cov={package_name}"], capture_output=True, text=True ) assert result.returncode == 0, "Pytest run failed" assert "coverage" in result.stdout.lower(), "Coverage summary not found in terminal output" # Run pytest with coverage and HTML report result_html = subprocess.run( ["pytest", f"--cov={package_name}", "--cov-report=html"], capture_output=True, text=True ) assert result_html.returncode == 0, "Pytest HTML report run failed" html_report_path = Path("htmlcov/index.html") assert html_report_path.exists(), "HTML coverage report file does not exist" # Simple check that HTML file contains expected tags with open(html_report_path, "r", encoding="utf-8") as f: html_content = f.read() assert "<html" in html_content.lower() and "coverage" in html_content.lower(), "HTML report content invalid" # Run pytest with coverage and XML report result_xml = subprocess.run( ["pytest", f"--cov={package_name}", "--cov-report=xml"], capture_output=True, text=True ) assert result_xml.returncode == 0, "Pytest XML report run failed" xml_report_path = Path("coverage.xml") assert xml_report_path.exists(), "XML coverage report file does not exist" # Parse XML to verify it is well-formed and contains coverage data tree = ET.parse(xml_report_path) root = tree.getroot() assert root.tag == "coverage", "Root tag of XML report is not 'coverage'" # Cleanup generated reports if html_report_path.exists(): for file in html_report_path.parent.glob("**/*"): if file.is_file(): file.unlink() html_report_path.parent.rmdir() if xml_report_path.exists(): xml_report_path.unlink()
This test automates the manual steps to generate coverage reports in three formats using pytest and pytest-cov.
First, it runs pytest with coverage enabled and checks the terminal output for coverage summary text.
Next, it runs pytest again to generate an HTML report, then verifies the 'htmlcov/index.html' file exists and contains expected HTML content.
Then, it runs pytest to generate an XML report and parses the 'coverage.xml' file to confirm it is valid XML with the root tag 'coverage'.
Finally, it cleans up the generated report files to keep the project directory clean.
This approach uses subprocess to run commands, file checks for report existence, and content parsing for validation, following best practices for test automation.
Now add data-driven testing to generate coverage reports for three different package names
Practice
Solution
Step 1: Understand coverage report purpose
Coverage reports show which lines or parts of code were executed during tests.Step 2: Compare options with coverage purpose
Only To show which parts of the code were tested and which were not correctly describes this purpose; others describe unrelated actions.Final Answer:
To show which parts of the code were tested and which were not -> Option DQuick Check:
Coverage report = tested code visibility [OK]
- Confusing coverage with test execution speed
- Thinking coverage generates test data
- Believing coverage fixes bugs automatically
Solution
Step 1: Recall pytest coverage report options
Common options include 'term' for terminal, 'html' for HTML, and 'xml' for XML reports.Step 2: Match option to HTML report
Only '--cov-report=html' generates an HTML report.Final Answer:
--cov-report=html -> Option CQuick Check:
HTML report option = --cov-report=html [OK]
- Using --cov-report=xml for HTML report
- Confusing term with html option
- Using non-existent --cov-report=summary
pytest --cov=myapp --cov-report=term-missingWhat will the terminal output show?
Solution
Step 1: Understand --cov-report=term-missing
This option shows coverage summary in terminal and highlights missing lines.Step 2: Match output to options
A summary of coverage with missing lines shown matches terminal summary with missing lines; others describe HTML, XML, or no output.Final Answer:
A summary of coverage with missing lines shown -> Option BQuick Check:
term-missing = terminal summary with missing lines [OK]
- Thinking term-missing opens HTML report
- Expecting XML output from term-missing
- Assuming no coverage info is shown
pytest --cov=myapp --cov-report=html but no HTML report was generated. What is the most likely cause?Solution
Step 1: Check where HTML report is saved
By default, pytest-cov saves HTML reports in 'htmlcov' folder in current directory.Step 2: Understand common confusion
Users may think no report generated if they don't check 'htmlcov' folder; plugin installation is needed but question assumes it is installed.Final Answer:
The HTML report is saved in the current directory as 'htmlcov' -> Option AQuick Check:
HTML report folder = htmlcov [OK]
- Assuming HTML report appears in terminal
- Forgetting to look in 'htmlcov' folder
- Thinking XML option is needed for HTML
Solution
Step 1: Identify XML report option
The '--cov-report=xml' option generates coverage results in XML format.Step 2: Match option to CI tool requirement
CI tools needing XML input require this exact option; others generate HTML or terminal output.Final Answer:
pytest --cov=myapp --cov-report=xml -> Option AQuick Check:
XML report option = --cov-report=xml [OK]
- Using HTML or terminal options for XML output
- Not specifying any --cov-report option
- Confusing term-missing with XML
