Testing#
The project ships with two complementary test suites that together give
100% statement and branch coverage of core_extensions.
tests/
├── unit/
│ ├── cli/
│ │ └── tests_aliased_group.py # AliasedGroup unit tests
│ └── decorators/
│ └── tests_retry.py # SimpleRetry unit tests
└── integration/
├── test_cli_integration.py # AliasedGroup end-to-end tests
└── test_retry_integration.py # SimpleRetry end-to-end tests
Unit Tests#
Unit tests cover each class in isolation. External collaborators (loggers, tenacity internals) are replaced with mocks so that every branch of the production code can be exercised independently and deterministically.
AliasedGroup (tests/unit/cli/tests_aliased_group.py)
Covers every public method of AliasedGroup: command(), group(),
add_command(), format_commands(), and get_command(). Edge cases
include bare-decorator usage (no parentheses), alias collision detection,
hidden commands, subgroups with cls=AliasedGroup, and the full
--help output format.
SimpleRetry (tests/unit/decorators/tests_retry.py)
Covers __init__ validation (conflicting kwargs, max_delay < base_delay),
create_decorator (empty tuple guard), and the after_error /
before_sleep callbacks in isolation using Mock objects.
Run unit tests:
pytest tests/unit/
Run a single unit test file:
pytest tests/unit/cli/tests_aliased_group.py
pytest tests/unit/decorators/tests_retry.py
Note
Unit test files follow a tests_*.py naming convention. The project’s
pyproject.toml configures pytest with python_files = ["tests_*.py",
"test_*.py"] so that both patterns are discovered automatically when
passing a directory path.
Integration Tests#
Integration tests exercise the full public API end-to-end with real
dependencies — Click’s CliRunner for the CLI and tenacity’s live retry
machinery for the decorator — using no mocks of internal collaborators.
AliasedGroup (tests/integration/test_cli_integration.py)
Builds a realistic multi-command CLI application and drives it through
Click’s CliRunner:
Canonical command names and every registered alias
Arguments and options passed through aliases without mutation
Subgroup accessed via parent alias (
i,infrastructure) with its own nested commands reachable by their nested aliases (prov,down)Commands registered imperatively via
add_command()with aliases--helpoutput: aliases rendered inline, hidden commands absent, alias annotation on the correct rowDuplicate alias registration raises
ValueErrorUnknown command returns a non-zero exit code
SimpleRetry (tests/integration/test_retry_integration.py)
Runs the complete tenacity retry cycle against live decorated functions:
Transient failure → success, verifying attempt count
All attempts exhausted:
reraise=Truepropagates the original exception;reraise=Falseraisestenacity.RetryErrorMultiple exception types in the tuple each trigger retry independently
Unregistered exception type propagates immediately without retry
Live log records checked for exception type, message, function name, and upcoming sleep duration (not cumulative)
reraiseoverride at decoration time overrides the instance defaultTwo decorators from the same
SimpleRetryinstance are independentReturn value preserved on a first-attempt success
Run integration tests:
pytest tests/integration/
Run a single integration test file:
pytest tests/integration/test_cli_integration.py
pytest tests/integration/test_retry_integration.py
Running All Tests#
Run both suites with a single command:
pytest tests/
Or using the helper script:
python manager.py run-tests
Coverage#
Generate a branch-coverage report for all core_extensions modules:
pytest tests/ \
--cov=core_extensions \
--cov-branch \
--cov-report=term-missing
Or using the helper script:
python manager.py run-coverage
The @t.overload stubs are excluded from coverage tracking via
.coveragerc (exclude_also = @.*overload) because overload
definitions are never executed at runtime — they exist solely for static
type checkers.
Expected output:
Name Stmts Miss Branch BrPart Cover
--------------------------------------------------------------------------
core_extensions/__init__.py 0 0 0 0 100%
core_extensions/cli/__init__.py 2 0 0 0 100%
core_extensions/cli/aliased_group.py 87 0 48 0 100%
core_extensions/decorators/__init__.py 2 0 0 0 100%
core_extensions/decorators/retry.py 41 0 12 0 100%
--------------------------------------------------------------------------
TOTAL 132 0 60 0 100%