Lab: CLI coverage
Write tests that cover all three ds-tool commands — happy paths, error paths, stdin confirmation, and env var injection.
- Write CliRunner tests covering the happy path for each subcommand
- Test error paths (missing argument, nothing to clean, empty scan)
- Test stdin input for a confirmation prompt
- Inject an environment variable and assert it affects behaviour
This lab writes tests for ds-tool — the multi-subcommand CLI from the Click
lab. We will cover all three commands (scan, report, clean), test both
the success and error paths for each, and handle the confirmation prompt in
clean via CliRunner's input= parameter.
The goal is a test suite that catches regressions without being fragile. By the end you will have tests for every meaningful branch.
The tool under test
For this lab, ds-tool is defined inline so the tests are self-contained.
In a real project it would live in its own module and the tests would import it.
Test 1 — scan: happy path
Test 2 — report: results and empty state
Test 3 — clean: confirmation prompts
Test 4 — env var injection
A tool that reads DS_TOOL_DEFAULT_EXT from the environment should use that
value when --ext is not provided. Test it with CliRunner's env= parameter:
Running pytest --cov=ds_tool tests/ after moving the tool into its own
module reports per-line coverage. Aim for every branch being exercised by at
least one test — not necessarily 100% line coverage, but 100% branch
coverage for the CLI paths that users can reach.
What you covered
The four test sections above exercise:
- Scan happy path (files found), scan error path (bad directory)
- Report with results, report with empty state
- Clean with stdin
y, clean with stdinn, clean with--yes, clean with no results - Env var override via
env=
That is every meaningful user-visible branch in ds-tool. Adding these tests
before shipping means a future refactor cannot silently break the output format,
the confirmation flow, or the environment-variable behaviour.
Where to go next
That completes the intermediate tier. The advanced tier covers distribution (building wheels, publishing to PyPI), writing plugins with entry points, and integrating CLIs into CI pipelines.