# pytest-mirror
A pluggy-based pytest plugin and CLI tool for ensuring your test suite mirrors your source code structure.
## Overview
**pytest-mirror** helps you:
- Ensure every Python module in your package has a corresponding test file.
- Quickly generate missing test stubs for new or existing code.
- Validate that your test suite structure matches your package structure.
- Integrate with pytest as a plugin or use as a standalone CLI.
Built with [pluggy](https://pluggy.readthedocs.io/) for extensible plugin architecture.
## Features
- **Test Structure Validation**: Checks for missing test files that should correspond to your package modules.
- **Test Stub Generation**: Automatically creates test files and `__init__.py` as needed, with a failing test stub.
- **CLI and Plugin**: Use as a command-line tool or as a pytest plugin.
- **Customizable**: Specify package and test directories.
## Installation
```bash
pip install pytest-mirror
```
For local development:
```bash
# Clone the repository and install in development mode
git clone https://github.com/dvonpasecky/pytest-mirror.git
cd pytest-mirror
pip install -e .
```
Or with uv:
```bash
uv sync
```
## Usage
### CLI
```bash
# With explicit directories:
pytest-mirror generate --package-dir src/your_package --tests-dir tests
pytest-mirror validate --package-dir src/your_package --tests-dir tests
# Or let pytest-mirror auto-detect your package and tests directories:
pytest-mirror generate
pytest-mirror validate
```
- `generate`: Creates missing test files for all modules in your package.
- `validate`: Checks for missing test files and reports any discrepancies.
### As a pytest Plugin
Add `pytest-mirror` to your test dependencies. The plugin will automatically:
1. **Validate** your test structure when running pytest
2. **Auto-generate** missing test files (unless disabled)
```bash
pytest
```
#### Plugin Configuration
You can customize the plugin behavior using:
- **Command-line flags:**
- `--mirror-package-dir` (path to your package)
- `--mirror-tests-dir` (path to your tests)
- `--mirror-no-generate` (disable automatic test generation)
If package and tests directories are not specified, the plugin will auto-detect the most likely directories.
**Auto-generation behavior**: By default, the plugin will automatically create missing test files when pytest runs. Use `--mirror-no-generate` to disable this and only validate structure.
## API
You can also use the core functions in your own scripts:
```python
from pytest_mirror import generate_missing_tests, find_missing_tests
# Generate missing test files
generate_missing_tests('src/your_package', 'tests')
# Find missing test files without creating them
missing = find_missing_tests('src/your_package', 'tests')
print(missing)
```
## Development
- All code is in `src/pytest_mirror/`.
- Tests are in `tests/` with 1:1 module mirroring.
- Run tests with:
```bash
pytest
# or with uv:
uv run pytest
```
- Lint and check style with:
```bash
ruff check src/ tests/
# or with uv:
uv run ruff check src/ tests/
```
## Contributing
Contributions are welcome! Please:
- Add or update tests for your changes.
- Ensure all tests and linters pass.
- Update this README if needed.
## License
MIT License. See [LICENSE](LICENSE).
---
*This project is not affiliated with pytest or pluggy, but is built to extend and complement them.*
Raw data
{
"_id": null,
"home_page": null,
"name": "pytest-mirror",
"maintainer": "Dan Von Pasecky",
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "pytest, testing, test-structure, plugin, cli, mirror, pluggy",
"author": "Dan Von Pasecky",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/c7/7c/3e45f5ab5ce857b766d8e878e80e1f97cd947b1970f12dc0b4e2a40f1ef4/pytest_mirror-0.1.1.tar.gz",
"platform": null,
"description": "# pytest-mirror\r\n\r\nA pluggy-based pytest plugin and CLI tool for ensuring your test suite mirrors your source code structure.\r\n\r\n## Overview\r\n\r\n**pytest-mirror** helps you:\r\n\r\n- Ensure every Python module in your package has a corresponding test file.\r\n- Quickly generate missing test stubs for new or existing code.\r\n- Validate that your test suite structure matches your package structure.\r\n- Integrate with pytest as a plugin or use as a standalone CLI.\r\n\r\nBuilt with [pluggy](https://pluggy.readthedocs.io/) for extensible plugin architecture.\r\n\r\n## Features\r\n\r\n- **Test Structure Validation**: Checks for missing test files that should correspond to your package modules.\r\n- **Test Stub Generation**: Automatically creates test files and `__init__.py` as needed, with a failing test stub.\r\n- **CLI and Plugin**: Use as a command-line tool or as a pytest plugin.\r\n- **Customizable**: Specify package and test directories.\r\n\r\n## Installation\r\n\r\n```bash\r\npip install pytest-mirror\r\n```\r\n\r\nFor local development:\r\n\r\n```bash\r\n# Clone the repository and install in development mode\r\ngit clone https://github.com/dvonpasecky/pytest-mirror.git\r\ncd pytest-mirror\r\npip install -e .\r\n```\r\n\r\nOr with uv:\r\n\r\n```bash\r\nuv sync\r\n```\r\n\r\n## Usage\r\n\r\n### CLI\r\n\r\n```bash\r\n# With explicit directories:\r\npytest-mirror generate --package-dir src/your_package --tests-dir tests\r\npytest-mirror validate --package-dir src/your_package --tests-dir tests\r\n\r\n# Or let pytest-mirror auto-detect your package and tests directories:\r\npytest-mirror generate\r\npytest-mirror validate\r\n```\r\n\r\n- `generate`: Creates missing test files for all modules in your package.\r\n- `validate`: Checks for missing test files and reports any discrepancies.\r\n\r\n### As a pytest Plugin\r\n\r\nAdd `pytest-mirror` to your test dependencies. The plugin will automatically:\r\n\r\n1. **Validate** your test structure when running pytest\r\n2. **Auto-generate** missing test files (unless disabled)\r\n\r\n```bash\r\npytest\r\n```\r\n\r\n#### Plugin Configuration\r\n\r\nYou can customize the plugin behavior using:\r\n\r\n- **Command-line flags:**\r\n - `--mirror-package-dir` (path to your package)\r\n - `--mirror-tests-dir` (path to your tests)\r\n - `--mirror-no-generate` (disable automatic test generation)\r\n\r\nIf package and tests directories are not specified, the plugin will auto-detect the most likely directories.\r\n\r\n**Auto-generation behavior**: By default, the plugin will automatically create missing test files when pytest runs. Use `--mirror-no-generate` to disable this and only validate structure.\r\n\r\n## API\r\n\r\nYou can also use the core functions in your own scripts:\r\n\r\n```python\r\nfrom pytest_mirror import generate_missing_tests, find_missing_tests\r\n\r\n# Generate missing test files\r\ngenerate_missing_tests('src/your_package', 'tests')\r\n\r\n# Find missing test files without creating them\r\nmissing = find_missing_tests('src/your_package', 'tests')\r\nprint(missing)\r\n```\r\n\r\n## Development\r\n\r\n- All code is in `src/pytest_mirror/`.\r\n- Tests are in `tests/` with 1:1 module mirroring.\r\n- Run tests with:\r\n\r\n```bash\r\npytest\r\n# or with uv:\r\nuv run pytest\r\n```\r\n\r\n- Lint and check style with:\r\n\r\n```bash\r\nruff check src/ tests/\r\n# or with uv:\r\nuv run ruff check src/ tests/\r\n```\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please:\r\n\r\n- Add or update tests for your changes.\r\n- Ensure all tests and linters pass.\r\n- Update this README if needed.\r\n\r\n## License\r\n\r\nMIT License. See [LICENSE](LICENSE).\r\n\r\n---\r\n\r\n*This project is not affiliated with pytest or pluggy, but is built to extend and complement them.*\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A pluggy-based pytest plugin and CLI tool for ensuring your test suite mirrors your source code structure",
"version": "0.1.1",
"project_urls": {
"Documentation": "https://github.com/dvonpasecky/pytest-mirror#readme",
"Homepage": "https://github.com/dvonpasecky/pytest-mirror",
"Repository": "https://github.com/dvonpasecky/pytest-mirror.git"
},
"split_keywords": [
"pytest",
" testing",
" test-structure",
" plugin",
" cli",
" mirror",
" pluggy"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "332d17fdbb020a702fc277424a3ed4c4db14f006c188cc8e828107b1cf27784f",
"md5": "84964cd5ba6ac57a10b55d9f4318d2b6",
"sha256": "6d343b2ef316114c8c059c2e77cc7d87e3e5f3ca1e54847acd74c6e00551ebe6"
},
"downloads": -1,
"filename": "pytest_mirror-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "84964cd5ba6ac57a10b55d9f4318d2b6",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 11432,
"upload_time": "2025-07-30T22:55:12",
"upload_time_iso_8601": "2025-07-30T22:55:12.847113Z",
"url": "https://files.pythonhosted.org/packages/33/2d/17fdbb020a702fc277424a3ed4c4db14f006c188cc8e828107b1cf27784f/pytest_mirror-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c77c3e45f5ab5ce857b766d8e878e80e1f97cd947b1970f12dc0b4e2a40f1ef4",
"md5": "cf9aea76ee13e2de074a96a3aa42da67",
"sha256": "252e39571070fc1ed74457b060c9c98cc301e73c47898a89ae9c7c046922e6fa"
},
"downloads": -1,
"filename": "pytest_mirror-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "cf9aea76ee13e2de074a96a3aa42da67",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 19786,
"upload_time": "2025-07-30T22:55:13",
"upload_time_iso_8601": "2025-07-30T22:55:13.906943Z",
"url": "https://files.pythonhosted.org/packages/c7/7c/3e45f5ab5ce857b766d8e878e80e1f97cd947b1970f12dc0b4e2a40f1ef4/pytest_mirror-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-30 22:55:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dvonpasecky",
"github_project": "pytest-mirror#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pytest-mirror"
}