Running GeoIPS Pytest Tests#
Basic Usage#
Run all tests (excluding limited dataset tests):
pytest
Run with verbose output:
pytest -v
Run tests from a specific test file:
pytest tests/unit_tests/test_example.py
Run specific test class:
pytest tests/unit_tests/test_example.py::TestClassName
Run specific test function:
pytest tests/unit_tests/test_example.py::test_function_name
Run specific method from test class:
pytest tests/unit_tests/test_example.py::TestClassName::test_method_name
Long-Running Unit Tests#
Run long-running unit tests (not included in default test paths):
pytest tests/unit_tests_long/
Combine long unit tests with regular tests:
pytest tests/unit_tests/ tests/unit_tests_long/
Run long unit tests with specific markers:
pytest tests/unit_tests_long/ -m "integration"
Marker Categories#
GeoIPS uses three categories of pytest markers:
- Concurrent Markers: Can be applied with any other marker
integration
,spans_multiple_packages
,limited_test_dataset_availability
- Repository-Level Markers: Mutually exclusive, test current repository functionality
base
,full
- System Implementation Markers: Mutually exclusive, test full GeoIPS system deployment
realtime
,scheduler
,database
,downloader
,external_preprocessing
,scrubber
For more information about what these markers mean, see our testing markers documentation.
Marker-Based Test Selection#
Repository-Level Markers#
Base Tests - Quick tests for minimal installations:
pytest -m "base"
Base tests complete very quickly and require only minimal installation for testing basic functionality within the current repository.
Full Tests - Comprehensive repository testing:
pytest -m "full"
Full tests require complete installation and test only functionality within
the current repository. These tests depend on geoips
being installed.
This includes all repository tests except those
marked as optional base
tests.
Run both base and full tests:
pytest -m "base or full"
Integration Test Markers#
Integration Tests - Cross-component functionality:
pytest -m "integration"
Integration tests verify functionality across multiple components and/or packages.
Exclude integration tests (unit tests only):
pytest -m "not integration"
Multi-Package Tests - Cross-repository dependencies:
pytest -m "spans_multiple_packages"
This tests functionality that could fail due to code in multiple repositories (e.g., plugin validation across repos).
Limited Dataset Tests - Restricted data availability:
pytest -m "limited_test_dataset_availability"
Run just tests that may not be available to all users due to dataset access restrictions or a lack of a pre-packaged opensource testing set.
GeoIPS System Implementation Markers#
These markers test complete GeoIPS system deployments for real-time processing. Most GeoIPS developers will not use these markers.
Real-time Tests - End-to-end processing:
pytest -m "realtime"
Tests full real-time functionality using complete procflow/workflow configs and all installed plugins.
Scheduler Tests - Task scheduling:
pytest -m "scheduler"
Tests scheduling capabilities for processing workflows.
Database Tests - Database integration:
pytest -m "database"
Tests database integrations.
Downloader Tests - Data ingestion:
pytest -m "downloader"
Tests automated data download and ingestion functions.
External Preprocessing Tests - Third-party integration:
pytest -m "external_preprocessing"
Tests/runs external preprocessing tools (e.g., CLAVR-x, CSPP) that are not part of core GeoIPS.
Scrubber Tests - Data cleanup:
pytest -m "scrubber"
Tests data cleanup and maintenance functions.
Combined Marker Examples#
Run base integration tests:
pytest -m "base and integration"
Run full tests excluding those requiring external datasets:
pytest -m "full and not limited_test_dataset_availability"
Run all system implementation tests:
pytest -m "realtime or scheduler or database or downloader or external_preprocessing or scrubber"
Run integration tests that don’t span multiple packages:
pytest -m "integration and not spans_multiple_packages"
Pattern Matching Examples#
Test Name Patterns
Run tests containing “reader” in the name:
pytest -k "reader"
Run tests for specific functionality:
pytest -k "test_colormap"
Run tests NOT containing specific words:
pytest -k "not slow"
Combine multiple patterns with AND:
pytest -k "reader and viirs"
Combine multiple patterns with OR:
pytest -k "reader or writer"
Complex pattern combinations:
pytest -k "(reader or writer) and not slow"
File Pattern Examples
Run all reader tests:
pytest -k "test_*_reader"
Run all tests ending with “integration”:
pytest -k "*integration"
Run tests matching class patterns:
pytest -k "TestReader or TestWriter"
Coverage and Output Options#
Coverage Reports
Generate HTML coverage report:
pytest --cov-report=html
Generate XML coverage report:
pytest --cov-report=xml
Generate coverage report to terminal:
pytest --cov-report=term
Show missing lines in terminal coverage:
pytest --cov-report=term-missing
Generate annotated source code coverage:
pytest --cov-report=annotate
Combine multiple coverage formats:
pytest --cov-report=html --cov-report=term-missing
Specify coverage source directory:
pytest --cov=geoips --cov-report=html
Set coverage output directory:
pytest --cov-report=html:htmlcov
Exclude files from coverage:
pytest --cov=geoips --cov-report=html --cov-config=.coveragerc
Show coverage for specific modules only:
pytest --cov=geoips.interfaces --cov-report=term-missing
Fail if coverage below threshold:
pytest --cov=geoips --cov-fail-under=80
Test Execution Control
Stop on first failure:
pytest -x
Stop after N failures:
pytest --maxfail=3
Run failed tests first:
pytest --ff
Run last failed tests only:
pytest --lf
Run new tests first:
pytest --nf
Output Formatting
Show only failures and errors:
pytest -rf
Show extra test summary (all except passed):
pytest -ra
Show all test outcomes:
pytest -rA
Show skipped tests:
pytest -rs
Show expected failures:
pytest -rx
Quiet output (reduce verbosity):
pytest -q
Extra verbose output:
pytest -vv
Show local variables in tracebacks:
pytest -l
Capture output (show print statements):
pytest -s
Disable output capturing completely:
pytest --capture=no
Traceback Options
Short traceback format:
pytest --tb=short
Long traceback format (default):
pytest --tb=long
No traceback:
pytest --tb=no
Only show one line per failure:
pytest --tb=line
Native Python traceback:
pytest --tb=native
Progress and Timing
Show slowest test durations:
pytest --durations=10
Show all test durations:
pytest --durations=0
Show test progress as percentage:
pytest --tb=no -q --durations=0
Disable duration reporting:
pytest --durations=0
Warning Control
Disable warnings:
pytest --disable-warnings
Show warnings summary:
pytest -rw
Turn warnings into errors:
pytest -W error
Filter specific warnings:
pytest -W ignore::DeprecationWarning
Managing Pytest Output and Logging#
Pytest can generate substantial output, especially when running comprehensive test suites with verbose logging. This section covers techniques for capturing, redirecting, and managing pytest output effectively.
Redirecting Output to Files
Capture all pytest output to a file:
pytest > test_results.txt 2>&1
Separate stdout and stderr:
pytest > test_output.txt 2> test_errors.txt
Append to existing log files:
pytest >> test_log.txt 2>&1
Capture only test results (suppress pytest’s own output):
pytest -q > results.txt 2>&1
Create timestamped log files:
pytest > "test_$(date +%Y%m%d_%H%M%S).log" 2>&1
Control pytest verbosity levels:
pytest -v > verbose_output.txt # Standard verbose
pytest -vv > extra_verbose_output.txt # Extra verbose
pytest -q > quiet_output.txt # Minimal output
Filter output by test outcomes:
pytest -ra > all_summary.txt # All test summary info
pytest -rf > failures_only.txt # Only failures and errors
pytest -rs > skipped_tests.txt # Only skipped tests
Enable live logging to see real-time output:
pytest --log-cli-level=INFO > test_with_logs.txt 2>&1
Capture logs at different levels:
pytest --log-level=DEBUG > debug_logs.txt 2>&1
pytest --log-level=WARNING > warning_logs.txt 2>&1
Configure log format for file output:
pytest --log-cli-format="%(asctime)s [%(levelname)s] %(message)s" > formatted_logs.txt 2>&1
Use progress indicators for long-running tests:
pytest --tb=line -q | tee progress.log
Rotate logs by test session:
pytest > "session_$(date +%s).log" 2>&1
Split output by test categories:
pytest -m "base" > base_tests.log 2>&1
pytest -m "integration" > integration_tests.log 2>&1
Output Size Management
Limit traceback length to reduce file size:
pytest --tb=short > compact_results.txt 2>&1
pytest --tb=no > minimal_results.txt 2>&1
Compress output files automatically:
pytest 2>&1 | gzip > test_results.gz
Real-time Monitoring
Monitor test progress in real-time:
pytest | tee test_output.txt
Follow log files during test execution:
pytest > test.log 2>&1 &
tail -f test.log
Run multiple test configurations with separate logs:
pytest -m "base" > base.log 2>&1
pytest -m "integration" > integration.log 2>&1
pytest -m "full" > full.log 2>&1
Multi-Package Coverage Example#
Run tests across all GeoIPS plugin packages with comprehensive coverage:
cd $GEOIPS_PACKAGES_DIR
coverage run --omit=*test* --source ./.. --module \
pytest -m '$pytest_mark' \
--junit-xml=/output/test-artifacts/pytest.xml \
--html=/output/test-artifacts/pytest.html --self-contained-html
coverage json -o /output/test-artifacts/coverage.json --pretty-print
coverage lcov -o /output/test-artifacts/coverage.lcov
coverage html -d /output/test-artifacts/coverage-html
- This example:
Uses
coverage run
to collect coverage data across all packagesOmits test files from coverage analysis with
--omit=*test*
Sets source directory to parent directory with
--source ./..
Runs pytest as a module with specified markers
Generates JUnit XML for CI/CD integration
Creates self-contained HTML test report
Exports coverage in multiple formats (JSON, LCOV, HTML)
Advanced Usage#
Parallel Execution
Run tests in parallel (requires pytest-xdist):
pytest -n auto
Specify number of parallel workers:
pytest -n 4
Distribute tests across multiple CPUs:
pytest -n logical
Complex Examples
Run with custom markers and options:
pytest -m "integration and not limited_test_dataset_availability" --cov-report=html -v
Exclude specific directories:
pytest --ignore=tests/integration_tests/
Include long unit tests with coverage:
pytest tests/unit_tests/ tests/unit_tests_long/ --cov-report=html
Pattern matching with coverage:
pytest -k "reader" --cov=geoips.interfaces.readers --cov-report=term-missing
Development and Debugging
Dry run (collect tests without running):
pytest --collect-only
Debug mode (drop into debugger on failures):
pytest --pdb
Drop into debugger on first failure:
pytest -x --pdb
Set trace immediately:
pytest --trace
CI/CD Integration
Create JUnit XML output for CI/CD:
pytest --junit-xml=results.xml
Create JSON report:
pytest --json-report --json-report-file=report.json
Combine XML and coverage for CI:
pytest --junit-xml=results.xml --cov-report=xml --cov-report=term
Performance Testing
Run with benchmark plugin (if installed):
pytest --benchmark-only
Profile test execution:
pytest --profile
Memory usage profiling:
pytest --memray
Extended Pytest Functionality#
- Core Extensions
pytest-cov - Coverage reporting
pytest-xdist - Parallel test execution
pytest-html - HTML test reports
- Development Tools
pytest-mock - Enhanced mocking capabilities
pytest-benchmark - Performance benchmarking
pytest-memray - Memory profiling
- CI/CD Integration
pytest-json-report - JSON test reports
pytest-timeout - Test timeout handling
pytest-rerunfailures - Retry failed tests
- Quality Assurance
pytest-flake8 - Code style checking
pytest-mypy - Type checking integration
pytest-clarity - Better assertion output