mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-03-09 12:50:23 -05:00
Merge 13d72c5762
into 05c8023a27
This commit is contained in:
commit
74e0bb80b0
7 changed files with 249 additions and 1 deletions
28
.coveragerc
Normal file
28
.coveragerc
Normal file
|
@ -0,0 +1,28 @@
|
|||
[coverage:run]
|
||||
source = yt_dlp, devscripts
|
||||
omit =
|
||||
*/extractor/lazy_extractors.py
|
||||
*/__pycache__/*
|
||||
*/test/*
|
||||
*/yt_dlp/compat/_deprecated.py
|
||||
*/yt_dlp/compat/_legacy.py
|
||||
data_file = .coverage
|
||||
|
||||
[coverage:report]
|
||||
exclude_lines =
|
||||
pragma: no cover
|
||||
def __repr__
|
||||
raise NotImplementedError
|
||||
if __name__ == .__main__.:
|
||||
pass
|
||||
raise ImportError
|
||||
except ImportError:
|
||||
warnings\.warn
|
||||
if TYPE_CHECKING:
|
||||
|
||||
[coverage:html]
|
||||
directory = .coverage-reports/html
|
||||
title = yt-dlp Coverage Report
|
||||
|
||||
[coverage:xml]
|
||||
output = .coverage-reports/coverage.xml
|
66
.github/workflows/coverage.yml
vendored
Normal file
66
.github/workflows/coverage.yml
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
name: Code Coverage
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: pip
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -e ".[dev]"
|
||||
pip install pytest-cov
|
||||
|
||||
- name: Run coverage tests in parallel
|
||||
run: |
|
||||
# Create a simple script to run coverage tests in parallel
|
||||
cat > run_parallel_coverage.py << 'EOF'
|
||||
import concurrent.futures
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def run_coverage(args):
|
||||
test_path, module_path = args
|
||||
cmd = ['python', '-m', 'devscripts.run_coverage', test_path, module_path]
|
||||
return subprocess.run(cmd, check=True)
|
||||
|
||||
coverage_tests = [
|
||||
('test/test_utils.py', 'yt_dlp.utils'),
|
||||
('test/test_YoutubeDL.py', 'yt_dlp.YoutubeDL'),
|
||||
('test/devscripts', 'devscripts')
|
||||
]
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
|
||||
futures = [executor.submit(run_coverage, test) for test in coverage_tests]
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
try:
|
||||
future.result()
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running coverage: {e}")
|
||||
sys.exit(1)
|
||||
EOF
|
||||
|
||||
# Run the script
|
||||
python run_parallel_coverage.py
|
||||
|
||||
- name: Archive coverage results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: |
|
||||
.coverage-reports/html/
|
||||
.coverage-reports/coverage.xml
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -127,3 +127,6 @@ yt-dlp.zip
|
|||
# Plugins
|
||||
ytdlp_plugins/
|
||||
yt-dlp-plugins
|
||||
|
||||
# Coverage
|
||||
/.coverage-reports/
|
||||
|
|
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())
|
|
@ -81,6 +81,7 @@ static-analysis = [
|
|||
test = [
|
||||
"pytest~=8.1",
|
||||
"pytest-rerunfailures~=14.0",
|
||||
"pytest-cov~=6.0",
|
||||
]
|
||||
pyinstaller = [
|
||||
"pyinstaller>=6.11.1", # Windows temp cleanup fixed in 6.11.1
|
||||
|
@ -161,11 +162,12 @@ features = ["test"]
|
|||
dependencies = [
|
||||
"pytest-randomly~=3.15",
|
||||
"pytest-xdist[psutil]~=3.5",
|
||||
"pytest-cov~=6.0",
|
||||
]
|
||||
|
||||
[tool.hatch.envs.hatch-test.scripts]
|
||||
run = "python -m devscripts.run_tests {args}"
|
||||
run-cov = "echo Code coverage not implemented && exit 1"
|
||||
run-cov = "python -m devscripts.run_coverage {args}"
|
||||
|
||||
[[tool.hatch.envs.hatch-test.matrix]]
|
||||
python = [
|
||||
|
|
39
test/README.md
Normal file
39
test/README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# yt-dlp Tests
|
||||
|
||||
This directory contains tests for the yt-dlp codebase.
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Using hatch (requires `pip install hatch`)
|
||||
|
||||
```bash
|
||||
# Run tests for a specific test file
|
||||
hatch run hatch-test:run test/test_utils.py
|
||||
|
||||
# Run a specific test class or method
|
||||
hatch run hatch-test:run test/test_utils.py::TestUtil
|
||||
hatch run hatch-test:run test/test_utils.py::TestUtil::test_url_basename
|
||||
|
||||
# Run with verbosity
|
||||
hatch run hatch-test:run -- test/test_utils.py -v
|
||||
```
|
||||
|
||||
### Using pytest directly
|
||||
|
||||
```bash
|
||||
# Run a specific test file
|
||||
python -m pytest test/test_utils.py
|
||||
|
||||
# Run a specific test class or method
|
||||
python -m pytest test/test_utils.py::TestUtil
|
||||
python -m pytest test/test_utils.py::TestUtil::test_url_basename
|
||||
|
||||
# Run with verbosity
|
||||
python -m pytest -v test/test_utils.py
|
||||
```
|
||||
|
||||
**Important:** Always run tests from the project root directory, not from a subdirectory.
|
||||
|
||||
## Code Coverage
|
||||
|
||||
For information on running tests with code coverage, see the documentation in `.coverage-reports/README.md`.
|
Loading…
Reference in a new issue