What are code coverage and static analysis tools and why are they useful?
**Code coverage** quantifies how much of your source code is exercised by a test suite. The standard Python tool is `coverage.py`, typically invoked via `pytest --cov`. It instruments the bytecode to track which lines execute. The report shows line coverage (percentage of lines hit) and optionally branch coverage (whether both sides of every conditional were reached). Branch coverage is strictly more informative because 100% line coverage can still miss the false branch of an `if` statement.
Coverage percentage is a proxy metric, not a quality metric. High coverage with weak assertions proves nothing. The useful workflow is to run coverage after adding tests, look at the HTML report to find uncovered branches, and add targeted tests for logic paths that represent real risk.
**Static analysis** inspects source code without executing it. Tools fall into several categories:
- **Style / formatting**: `flake8` (PEP 8 violations), `black` (opinionated auto-formatter), `isort` (import ordering). These are zero-configuration in CI. - **Type checking**: `mypy` and `pyright` analyze type annotations to catch type errors before runtime. They are most valuable in large codebases where function signatures would otherwise be implicit. - **Security scanning**: `bandit` flags common security issues — hardcoded passwords, use of eval, insecure hash algorithms. - **Complexity**: `radon` or `flake8-cognitive-complexity` measure cyclomatic complexity per function. High complexity correlates with bug density and difficulty of testing.
In a modern Python project, these tools run together in CI: black and isort in check mode for formatting, flake8 or ruff for lint, mypy for type checking, and coverage after the test run. `ruff` is increasingly popular because it replaces flake8, isort, and several plugins with a single fast Rust-based tool.
The interview-relevant distinction: coverage tells you what was executed; static analysis tells you what is wrong before execution. Both are complementary, not substitutes.
Distinguishes line from branch coverage, names at least two static analysis categories with a tool per category.
Explains why high coverage does not equal high quality, distinguishes style/type/security analysis, and names ruff or mypy in a modern CI context.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment