mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-12-18 22:19:19 +00:00
[test] Add code coverage framework
Implement a comprehensive test coverage framework that integrates with pytest-cov to generate code coverage reports for the yt-dlp codebase. Key components: - Configuration file (.coveragerc) with appropriate include/exclude patterns - Helper script (run_coverage.py) with parallel report generation - GitHub Actions workflow for automatic coverage reporting on PRs and pushes - Support for Hatch testing environment and CLI integration - Testing documentation for running coverage reports - Sample test for demonstrating coverage reporting
This commit is contained in:
5
devscripts/cov-combine
Executable file
5
devscripts/cov-combine
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This script is a helper for the Hatch test coverage command
|
||||
# It's called by `hatch test --cover`
|
||||
|
||||
coverage combine "$@"
|
||||
105
devscripts/run_coverage.py
Executable file
105
devscripts/run_coverage.py
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Script to run coverage tests for yt-dlp
|
||||
#
|
||||
# Usage:
|
||||
# python -m devscripts.run_coverage [test_path] [module_path] [additional pytest args]
|
||||
#
|
||||
# Examples:
|
||||
# python -m devscripts.run_coverage # Test everything
|
||||
# python -m devscripts.run_coverage test/devscripts # Test devscripts
|
||||
# python -m devscripts.run_coverage test/test_utils.py yt_dlp.utils # Test specific module
|
||||
# python -m devscripts.run_coverage test/test_utils.py "yt_dlp.utils,yt_dlp.YoutubeDL" # Test multiple modules
|
||||
# python -m devscripts.run_coverage test -v # With verbosity
|
||||
#
|
||||
# Using hatch:
|
||||
# hatch run hatch-test:run-cov [args] # Same arguments as above
|
||||
# hatch test --cover # Run all tests with coverage
|
||||
#
|
||||
# Important:
|
||||
# - Always run this script from the project root directory
|
||||
# - Test paths are relative to the project root
|
||||
# - Module paths use Python import syntax (with dots)
|
||||
# - Coverage reports are generated in .coverage-reports/
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
script_dir = Path(__file__).parent
|
||||
repo_root = script_dir.parent
|
||||
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
|
||||
if not args:
|
||||
# Default to running all tests
|
||||
test_path = 'test'
|
||||
module_path = 'yt_dlp,devscripts'
|
||||
elif len(args) == 1:
|
||||
test_path = args[0]
|
||||
# Try to guess the module path from the test path
|
||||
if test_path.startswith('test/devscripts'):
|
||||
module_path = 'devscripts'
|
||||
elif test_path.startswith('test/'):
|
||||
module_path = 'yt_dlp'
|
||||
else:
|
||||
module_path = 'yt_dlp,devscripts'
|
||||
else:
|
||||
test_path = args[0]
|
||||
module_path = args[1]
|
||||
|
||||
# Initialize coverage reports directory
|
||||
cov_dir = repo_root / '.coverage-reports'
|
||||
cov_dir.mkdir(exist_ok=True)
|
||||
html_dir = cov_dir / 'html'
|
||||
html_dir.mkdir(exist_ok=True)
|
||||
|
||||
# Run pytest with coverage
|
||||
cmd = [
|
||||
'python', '-m', 'pytest',
|
||||
f'--cov={module_path}',
|
||||
'--cov-config=.coveragerc',
|
||||
'--cov-report=term-missing',
|
||||
test_path,
|
||||
]
|
||||
|
||||
if len(args) > 2:
|
||||
cmd.extend(args[2:])
|
||||
|
||||
print(f'Running coverage on {test_path} for module(s) {module_path}')
|
||||
print(f'Command: {" ".join(cmd)}')
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, check=True)
|
||||
|
||||
# Generate reports after the test run in parallel
|
||||
import concurrent.futures
|
||||
|
||||
def generate_html_report():
|
||||
return subprocess.run([
|
||||
'python', '-m', 'coverage', 'html',
|
||||
], check=True)
|
||||
|
||||
def generate_xml_report():
|
||||
return subprocess.run([
|
||||
'python', '-m', 'coverage', 'xml',
|
||||
], check=True)
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
|
||||
html_future = executor.submit(generate_html_report)
|
||||
xml_future = executor.submit(generate_xml_report)
|
||||
# Wait for both tasks to complete
|
||||
concurrent.futures.wait([html_future, xml_future])
|
||||
|
||||
print(f'\nCoverage reports saved to {cov_dir.as_posix()}')
|
||||
print(f'HTML report: open {cov_dir.as_posix()}/html/index.html')
|
||||
return result.returncode
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f'Error running coverage: {e}')
|
||||
return e.returncode
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user