如何构建无生产代码依赖的pytest纯测试Python包?
Great question! Building a pure test-only Python package for remote subsystem testing (like your REST API use case) is totally feasible—you just need to tweak your packaging setup since standard docs focus on mixed production/test code. Let’s break down your questions with practical solutions:
1. How to Build a Test-Only Python Package?
The key is to configure your modern packaging tool (we’ll use pyproject.toml over legacy setup.py) to include all test-related files (test cases, fixtures, conftest.py, utils, and configs) without any production code. Here’s a step-by-step setup:
Example Package Structure
First, organize your files into an importable package structure (this helps pytest find fixtures and utilities easily):
my-remote-test-suite/ ├── tests/ │ ├── __init__.py # Marks this as a Python package │ ├── conftest.py │ ├── test_api_core.py │ ├── fixtures/ │ │ ├── __init__.py │ │ └── api_fixtures.py │ └── utils/ │ ├── __init__.py │ └── test_helpers.py ├── pyproject.toml └── pytest.ini
Configure pyproject.toml
This file tells setuptools how to build your package, including dependencies and all test assets:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "my-remote-test-suite" version = "0.1.0" description = "Remote test suite for subsystem REST API validation" dependencies = [ "pytest>=7.0", "requests>=2.31.0", # Add other test dependencies (e.g., pytest-httpx, pytest-cov) ] # Include the tests directory as a Python package [tool.setuptools.packages.find] where = ["tests"] include = ["tests*"] # Ensure all test-related files are included in the build [tool.setuptools.package-data] "tests" = ["*.py", "fixtures/*.py", "utils/*.py"] include = ["pytest.ini"]
Optional: Legacy MANIFEST.ini
If you still need to use MANIFEST.ini instead of pyproject.toml package data, add this to capture all test files:
include pytest.ini recursive-include tests *.py
Build and Install
Run these commands to build and install your package:
pip install build python -m build pip install dist/my_remote_test_suite-0.1.0-py3-none-any.whl
Once installed, you can run tests directly with:
pytest --pyargs my-remote-test-suite
2. Alternative Package Structures (Pros & Cons)
There are a few valid approaches depending on your scalability and deployment needs:
Flat Package Structure
- Structure: All test files, fixtures, and utils live directly in the root
tests/directory (no nested subdirs) - Pros: Extremely simple to configure; easy for small teams to navigate
- Cons: Becomes messy as you add more test cases; no way to group tests by subsystem/feature
Namespace Package Structure
- Structure: Use a nested namespace (e.g.,
com/mycompany/testsuite/subsystem_a/) to avoid package name conflicts - Pros: Ideal for large organizations with multiple test suites; allows splitting tests into separate maintainable sub-packages
- Cons: Requires careful namespace configuration; slightly steeper learning curve
Data File Deployment (Like avocado-framework)
- Structure: Deploy test files as system/user data files instead of Python package files (e.g.,
/usr/share/my-test-suite/testsor~/.local/share/my-test-suite/tests) - Setup: Add this to your
pyproject.tomlto specify data file paths:[tool.setuptools.data_files] "share/my-test-suite/tests" = ["tests/*.py", "tests/fixtures/*.py"] "share/my-test-suite" = ["pytest.ini"] - Pros: Keeps test files separate from
site-packages, avoiding clutter; great for system-wide test framework deployments - Cons: Users need to specify the test directory path when running pytest (or you’ll need to build a CLI wrapper to auto-locate it); updating tests requires a full package reinstall
Editable Development Install
- Structure: Keep your existing "rough" structure and install with
pip install -e . - Pros: Changes to test files are reflected immediately (no reinstall needed); perfect for active development
- Cons: Not suitable for production deployment; ties the package to your local directory structure
3. Where Should Test Files & Dependencies Be Installed?
The answer depends on your deployment goals:
Option 1: Install to site-packages (As a Python Package)
- Location: Test files/fixtures/utils are installed alongside other Python packages in your environment’s
site-packages/tests/(or your package’s dedicated directory) - Pros: Seamless integration with pytest—users can run tests with
pytest --pyargs <package-name>without manually specifying paths; fixtures/utils are importable by test cases - Cons: Adds test-related files to
site-packages, which some teams prefer to keep reserved for production code
Option 2: Install to System/User Data Directories
- Location: Test files go to standard data directories like
/usr/share/(system-wide) or~/.local/share/(user-specific), as used by avocado-framework - Pros: Keeps
site-packagesclean; ideal for test suites that need to be accessible system-wide without polluting Python environments - Cons: Requires extra work to make tests easy to run (e.g., building a CLI command to auto-detect the test directory); less integrated with pytest’s default discovery
Pro Tip
If you choose the data file approach, add a CLI entry point to your package to run tests automatically. For example, add this to pyproject.toml:
[project.scripts] run-subsystem-tests = "tests.runner:main"
Then create tests/runner.py:
import pytest import os import sys def main(): # Locate the installed test directory test_dir = os.path.join(sys.prefix, "share", "my-test-suite", "tests") pytest.main([test_dir]) if __name__ == "__main__": main()
Users can then run tests with just run-subsystem-tests.
内容的提问来源于stack exchange,提问作者thinwybk

