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

  • --help output: aliases rendered inline, hidden commands absent, alias annotation on the correct row

  • Duplicate alias registration raises ValueError

  • Unknown 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=True propagates the original exception; reraise=False raises tenacity.RetryError

  • Multiple 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)

  • reraise override at decoration time overrides the instance default

  • Two decorators from the same SimpleRetry instance are independent

  • Return 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%