CI/Testing Workflow ๐งช#
Continuous Integration (CI) is essential for maintaining high-quality code by catching issues early. This guide covers CI testing and quality checks for Ultralytics projects.
CI Actions ๐#
All PRs must pass automated CI checks before merging. Our CI pipeline includes:
CI Tests#
Primary CI test running unit tests, linting checks, and comprehensive tests.
Docker Deployment#
Validates deployment using Docker, ensuring Dockerfile and related scripts work correctly.
Broken Links#
Scans codebase for broken or dead links in markdown and HTML files.
CodeQL Analysis#
GitHub's semantic analysis tool for finding potential security vulnerabilities and maintaining code quality.
PyPI Publishing#
Validates project can be packaged and published to PyPI without errors.
Platform Testing ๐ฅ๏ธ#
Tests run on multiple environments:
- OS: Ubuntu, Windows, macOS
- Python: 3.8, 3.9, 3.10, 3.11, 3.12
Code Coverage ๐#
We use Codecov to measure and visualize code coverage, providing insights into how well tests exercise the codebase.
Coverage Integration#
Codecov integration provides:
- Detailed coverage insights
- Coverage comparisons between commits
- Visual overlays on code showing covered lines
- Coverage percentage for the
ultralyticspackage
View full coverage details at codecov.io/github/ultralytics/ultralytics.
Understanding Coverage#
Code coverage shows what percentage of code is executed during tests. High coverage indicates well-tested code but doesn't guarantee absence of bugs. Coverage helps identify untested areas that might be prone to errors.
Running Tests Locally ๐ฅ๏ธ#
Install Development Dependencies#
pip install -e ".[dev]"Run All Tests#
pytest tests/Run Specific Tests#
# Single file
pytest tests/test_engine.py
# Single test function
pytest tests/test_engine.py::test_train
# Tests matching pattern
pytest -k "export"
# Slow tests only
pytest -m slowRun with Coverage#
pytest --cov=ultralytics tests/Parallel Testing#
# Install pytest-xdist
pip install pytest-xdist
# Run tests in parallel
pytest -n autoWriting Tests โ๏ธ#
Test Structure#
from pathlib import Path
from ultralytics import YOLO
def test_model_export():
"""Test ONNX model export."""
model = YOLO("yolo26n.pt")
model.export(format="onnx")
assert Path("yolo26n.onnx").exists()Best Practices#
- Descriptive names:
test_export_onnx_format()nottest_1() - Single assertion: Test one thing per function
- Fast tests: Use small models/datasets
- Fixtures: Use pytest fixtures for setup/teardown
- Markers:
@pytest.mark.slowfor long-running tests
Test Organization#
tests/
โโโ test_engine.py # Training, validation, prediction
โโโ test_nn.py # Model architecture
โโโ test_data.py # Dataset handling
โโโ test_utils.py # Utility functions
โโโ test_exports.py # Export formatsTest Markers#
import pytest
@pytest.mark.slow
def test_full_training():
"""Test full training run (slow)."""
model = YOLO("yolo26n.pt")
model.train(data="coco128.yaml", epochs=1)Code Quality Checks ๐ฏ#
Formatting with Ruff#
# Check formatting
ruff check ultralytics/
# Auto-fix issues
ruff check --fix ultralytics/
# Format code
ruff format ultralytics/Learn more about code standards in our development workflow.
Type Checking#
# Run mypy (where configured)
mypy ultralytics/Docstring Formatting#
pip install ultralytics-actions# Auto-fix
ultralytics-actions-format-python-docstrings .CI Troubleshooting ๐ง#
Tests Pass Locally But Fail in CI#
Common causes:
- Platform-specific issues: Test on target OS
- Python version differences: Check version compatibility
- Missing dependencies: Verify CI config
- Timing/concurrency issues: Add retries or increase timeouts
Slow CI Runs#
Solutions:
- Use
@pytest.mark.slowfor expensive tests - Mock external dependencies
- Reduce test dataset sizes
- Parallelize with
pytest-xdist
Flaky Tests#
Fixes:
- Add retries for network-dependent tests
- Increase timeouts for slow operations
- Fix race conditions in async code
- Use deterministic random seeds
Performance Benchmarks ๐#
CI tracks key metrics:
- Inference speed (FPS)
- Memory usage
- Model size
- Export times
Significant regressions block merging. If metrics change:
- Verify change is expected
- Document reason in PR
- Get approval from maintainers
CI Status ๐#
Check CI status for all Ultralytics repositories at docs.ultralytics.com/help/CI.
Main Repository Badges#
Skipping CI Checks โ ๏ธ#
Add [skip ci] to commit message to skip CI (use sparingly):
git commit -m "Update README [skip ci]"Only for:
- Documentation-only changes
- Non-code file updates
- Emergency hotfixes (with approval)
Resources ๐#
- Official CI Guide - Complete CI documentation
- Development Workflow - PR process and code standards
- GitHub Actions Docs - CI configuration
- pytest Documentation - Testing framework
- Codecov - Coverage reports