Pytest plugin for automatic integration test marking and management
Project description
pytest-mark-integration
A pytest plugin for automatic integration test marking and management.
Features
- ๐ฏ Automatic Test Marking: Automatically marks tests as integration tests based on file path patterns
- ๐๏ธ Flexible Configuration: Configure default behavior via
pytest.iniorpyproject.toml - โก Smart Test Ordering: Runs unit tests before integration tests for faster feedback
- ๐ฆ Fail-Fast Support: Optionally skip integration tests when unit tests fail
- ๐ Plugin Integration: Seamlessly integrates with
pytest-covandpytest-timeout - ๐๏ธ Command-Line Control: Override default behavior with
--with-integrationand--without-integrationflags
Installation
Install using pip:
pip install pytest-mark-integration
Or using uv:
uv add pytest-mark-integration --dev
Quick Start
Once installed, the plugin automatically activates. By default:
- Tests are automatically marked if their file path contains
integration - Integration tests run by default (configurable)
- Unit tests run before integration tests (for faster feedback)
Example Test Structure
your_project/
โโโ tests/
โ โโโ unit/
โ โ โโโ test_utils.py # Not marked (runs first)
โ โโโ integration/
โ โ โโโ test_api.py # Auto-marked as integration
โ โโโ test_db_integration.py # Auto-marked (path contains "integration")
Running Tests
# Run all tests (including integration tests)
pytest
# Skip integration tests
pytest --without-integration
# Run only integration tests
pytest --with-integration -m integration
# Run tests with coverage (integration tests excluded from coverage by default)
pytest --cov
Configuration
Configuration Options
Configure via pytest.ini:
[pytest]
# Run integration tests by default (default: true)
run_integration_by_default = true
# Skip integration tests if unit tests fail (default: true)
fail_fast_on_unit_test_failure = true
Or via pyproject.toml:
[tool.pytest.ini_options]
run_integration_by_default = true
fail_fast_on_unit_test_failure = true
Command-Line Options
| Option | Description |
|---|---|
--with-integration |
Run integration tests (overrides config) |
--without-integration |
Skip integration tests (overrides config) |
--integration-cover |
Include integration tests in coverage reports |
--integration-timeout SECONDS |
Set timeout for integration tests (requires pytest-timeout) |
--integration-timeout-method METHOD |
Timeout method: thread or signal (requires pytest-timeout) |
How It Works
Automatic Marking
The plugin automatically adds the @pytest.mark.integration marker to tests when:
- The test file path contains the word
integration(case-insensitive) - The test is manually decorated with
@pytest.mark.integration
Note: The plugin uses paths relative to the pytest root directory to avoid false positives from parent directory names containing "integration".
Examples of auto-marked tests:
# tests/integration/test_api.py - โ
Auto-marked
def test_api_endpoint():
pass
# tests/test_database_integration.py - โ
Auto-marked
def test_db_connection():
pass
# integration_tests/test_system.py - โ
Auto-marked
def test_full_system():
pass
# tests/unit/test_helpers.py - โ Not marked
def test_helper_function():
pass
Test Execution Priority
The plugin ensures integration tests run after unit tests:
Execution Order:
1. Unit tests (no integration marker) โก Fast
2. Integration tests (@pytest.mark.integration) ๐ข Slower
This provides:
- Faster feedback during development
- Efficient CI/CD pipelines (fail fast on basic issues)
Fail-Fast Behavior
When fail_fast_on_unit_test_failure = true (default):
Unit Test โ FAIL โ
โ
Integration Tests โ SKIPPED โญ๏ธ
โ
Reason: "Skipping integration tests due to unit test failure"
This saves time by not running expensive integration tests when basic functionality is broken.
Manual Marking
You can still manually mark tests:
import pytest
@pytest.mark.integration
def test_external_api():
"""This test will be treated as an integration test"""
pass
Integration with Other Plugins
pytest-cov (Coverage)
By default, integration tests do not contribute to coverage reports (since unit tests should cover all code).
# Integration tests excluded from coverage
pytest --cov
# Include integration tests in coverage
pytest --cov --integration-cover
pytest-timeout
Set timeouts specifically for integration tests:
# Set 60-second timeout for integration tests
pytest --integration-timeout 60
# Use signal-based timeout method
pytest --integration-timeout 60 --integration-timeout-method signal
pytest-xdist (Parallel Execution)
The plugin is compatible with pytest-xdist for parallel test execution:
# Run tests in parallel across 4 workers
pytest -n 4
Note: In parallel mode, fail-fast behavior may not work perfectly since tests are distributed across multiple processes.
Configuration Priority
The plugin respects the following priority order:
-
Command-line flags (highest priority)
--with-integrationโ Always run integration tests--without-integrationโ Always skip integration tests
-
Configuration file (medium priority)
run_integration_by_default = true/false
-
Default behavior (lowest priority)
- Run integration tests (
run_integration_by_defaultdefaults totrue)
- Run integration tests (
Use Cases
Local Development
Fast feedback loop - skip slow integration tests:
# In pytest.ini
run_integration_by_default = false
pytest # Only unit tests run
CI/CD Pipeline
Run all tests in CI:
# In pyproject.toml
run_integration_by_default = true
fail_fast_on_unit_test_failure = true
pytest # All tests run, fail fast if unit tests fail
Pre-commit Hook
Quick validation before committing:
pytest --without-integration
Integration Test Suite
Run only integration tests:
pytest --with-integration -m integration
Examples
Example 1: Mixed Test Suite
# tests/unit/test_calculator.py
def test_add():
assert 1 + 1 == 2 # Runs first
# tests/integration/test_api.py
def test_api_health():
response = requests.get("http://api.example.com/health")
assert response.status_code == 200 # Runs second
# tests/test_database_integration.py
def test_database_connection():
db = Database()
assert db.connect() # Runs third (auto-marked due to filename)
$ pytest -v
tests/unit/test_calculator.py::test_add PASSED [ 33%]
tests/integration/test_api.py::test_api_health PASSED [ 66%]
tests/test_database_integration.py::test_database_connection PASSED [100%]
Example 2: Skip Integration Tests
$ pytest --without-integration -v
tests/unit/test_calculator.py::test_add PASSED [100%]
tests/integration/test_api.py::test_api_health SKIPPED (Integration tests skipped)
tests/test_database_integration.py::test_database_connection SKIPPED (Integration tests skipped)
Example 3: Fail-Fast Behavior
# tests/unit/test_calculator.py
def test_add():
assert 1 + 1 == 3 # โ FAILS
# tests/integration/test_api.py
def test_api_health():
# This test is skipped because unit test failed
pass
$ pytest -v
tests/unit/test_calculator.py::test_add FAILED [50%]
tests/integration/test_api.py::test_api_health SKIPPED [100%]
(Skipping integration tests due to unit test failure)
Troubleshooting
Integration Tests Not Being Marked
Problem: Tests in integration paths aren't being marked.
Solution: Ensure the file path (not just the directory name) contains integration:
# โ
Correct
tests/integration/test_api.py
tests/test_integration_api.py
# โ Won't work
int/test_api.py # "integration" not in path
Note: The plugin uses paths relative to the pytest root directory. If you're running tests from a subdirectory, ensure the relative path from the project root contains "integration".
Integration Tests Still Running After Unit Test Failure
Problem: Integration tests run even when unit tests fail.
Solution: Enable fail-fast in configuration:
[pytest]
fail_fast_on_unit_test_failure = true
Coverage Reports Include Integration Tests
Problem: Integration tests are included in coverage reports.
Solution: Remove --integration-cover flag (it's disabled by default):
pytest --cov # Integration tests excluded
Development
Setup Development Environment
# Clone repository
git clone https://github.com/yourusername/pytest-mark-integration.git
cd pytest-mark-integration
# Install dependencies with uv
uv sync --all-extras
# Or with pip
pip install -e ".[dev]"
Run Tests
make test
Code Quality
# Format code
make format
# Lint code
make lint
# Type check
make typecheck
Build and Publish
# Build distribution
make build
# Publish to TestPyPI
make publish-test
# Publish to PyPI
make publish
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Comparison with Similar Projects
This plugin combines and improves upon features from two existing projects:
Feature Comparison
| Feature | pytest-mark-integration (This Project) | pytest-integration | pytest-integration-mark |
|---|---|---|---|
| Auto-marking by path | โ
integration in path |
โ Manual only | โ
tests/integration/ folder only |
| Configurable folder | โ Any path with "integration" | โ N/A | โ
Via --integration-tests-folder |
| Default behavior | โ Run by default (configurable) | โ Run by default | โ Skip by default |
| Smart test ordering | โ Unit โ Integration | โ Unit โ Integration โ Slow | โ No ordering |
| Fail-fast on unit failure | โ Yes (configurable) | โ Yes | โ No |
| Multi-tier integration tests | โ Single tier | โ Two tiers (quick/slow) | โ Single tier |
| Coverage integration | โ Exclude by default | โ Exclude by default | โ Not handled |
| Timeout support | โ
Via --integration-timeout |
โ
Via --integration-timeout |
โ No |
| Configuration file | โ
pytest.ini / pyproject.toml |
โ Command-line only | โ Command-line only |
| CLI override | โ
--with/without-integration |
โ
--with/without-integration |
โ
--with-integration only |
| pytest-xdist compatible | โ Yes | โ ๏ธ Partial (documented limitation) | โ Yes |
| Marker name | @pytest.mark.integration |
@pytest.mark.integration_test |
@pytest.mark.integration |
| Python version | 3.10+ | Any | 3.7+ |
| Active maintenance | โ 2025 | โ ๏ธ Last updated 2020 | โ ๏ธ Last updated 2021 |
Detailed Comparison
vs. pytest-integration
pytest-integration is the original project that pioneered integration test management in pytest. Our project builds upon its foundation with modern improvements:
Advantages of pytest-mark-integration:
- โ
Automatic path-based marking: No need to manually add
@pytest.mark.integration_testto every test - โ
Flexible configuration: Configure behavior via
pytest.iniorpyproject.toml, not just command-line - โ Better defaults: Integration tests run by default (matches CI/CD workflows)
- โ
Simpler marker name:
integrationvs.integration_test - โ Modern codebase: Type hints, Python 3.10+, uses current pytest APIs
- โ Better path detection: Uses relative paths from project root to avoid false positives
Advantages of pytest-integration:
- โ Multi-tier tests: Supports both quick and slow integration tests (two-tier hierarchy)
- โ Cascading fail-fast: Stops slow integration tests if quick integration tests fail
Best for:
- pytest-mark-integration: Projects wanting automatic marking, modern Python, and simpler configuration
- pytest-integration: Projects needing multi-tier integration test hierarchies
vs. pytest-integration-mark
pytest-integration-mark focuses on automatically marking tests in a specific folder. Our project extends this concept significantly:
Advantages of pytest-mark-integration:
- โ
Flexible path matching: Any path containing "integration", not just
tests/integration/ - โ Run by default: Better for CI/CD (skip integration tests locally, run in CI)
- โ Smart ordering: Unit tests always run before integration tests
- โ Fail-fast support: Skip integration tests when unit tests fail (saves time)
- โ Coverage integration: Automatically excludes integration tests from coverage
- โ Timeout support: Set timeouts specifically for integration tests
- โ
Configuration file: Persistent settings via
pytest.iniorpyproject.toml - โ
Both CLI options:
--with-integrationand--without-integration
Advantages of pytest-integration-mark:
- โ Simpler: Fewer features, easier to understand
- โ Skip by default: Integration tests won't run unless explicitly requested
Best for:
- pytest-mark-integration: Production projects needing comprehensive integration test management
- pytest-integration-mark: Simple projects wanting basic auto-marking with minimal configuration
Migration Guide
From pytest-integration
# Old (pytest-integration)
@pytest.mark.integration_test
def test_api():
pass
@pytest.mark.slow_integration_test
def test_slow_api():
pass
# New (pytest-mark-integration)
# Automatic marking - no decorator needed if in integration path!
def test_api(): # Auto-marked if in tests/integration/test_api.py
pass
# Or manual marking with simpler name
@pytest.mark.integration
def test_api():
pass
# Note: No slow_integration_test tier (use timeout instead)
Configuration:
# pytest-integration (command-line only)
pytest --without-integration
# pytest-mark-integration (persistent config)
[pytest]
run_integration_by_default = false
From pytest-integration-mark
# Old (pytest-integration-mark)
# File: tests/integration/test_api.py
def test_api(): # Auto-marked only in tests/integration/
pass
# New (pytest-mark-integration)
# File: tests/integration/test_api.py
def test_api(): # Auto-marked (same behavior)
pass
# File: tests/test_db_integration.py
def test_db(): # ALSO auto-marked (path contains "integration")
pass
Command-line:
# pytest-integration-mark
pytest --with-integration # Run integration tests
# pytest-mark-integration
pytest --with-integration # Run integration tests
pytest --without-integration # Skip integration tests (new option!)
pytest # Run by default (configurable)
Why Choose pytest-mark-integration?
Choose this plugin if you want:
- ๐ฏ Zero-configuration auto-marking: Just name your files/folders with "integration"
- โ๏ธ Flexible configuration: Persistent settings in config files, not just CLI
- โก Smart execution: Unit tests first, fail-fast on failures
- ๐ Ecosystem integration: Works seamlessly with pytest-cov, pytest-timeout, pytest-xdist
- ๐ Better defaults: Designed for modern CI/CD workflows
- ๐ ๏ธ Active maintenance: Modern codebase with ongoing updates
Acknowledgments
Inspired by:
Changelog
See CHANGELOG.md for version history.
Support
- ๐ Documentation
- ๐ Issue Tracker
- ๐ฌ Discussions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_mark_integration-1.0.0.tar.gz.
File metadata
- Download URL: pytest_mark_integration-1.0.0.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b085bd4ceb9f9ad1a4c1defc342fec29b4aa024c43da02cc6b6dd09c270b7483
|
|
| MD5 |
e1ed88578e47090a0ae2d2707cee46b6
|
|
| BLAKE2b-256 |
b8463c04f90d1c32dc50d98f9fef487fdbaa45229dd5295d689b794e49492bcc
|
File details
Details for the file pytest_mark_integration-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pytest_mark_integration-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.16
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2eb4a796169aafc0f057c86d983a4d54a46626468ffc153fda2f066522b527af
|
|
| MD5 |
74538e495b2ee72210a16ee1ec7c3c51
|
|
| BLAKE2b-256 |
e218a1731c8594dd61e5bb6485c2e7e35c8e807deba4a9b63a5233f95c6f3515
|