---
type: reference
subtype: procedural
name: skill-smart-test
category: skill
tags: [skill, plugin]
source: plugin/skills/smart-test/SKILL.md
---

# Smart Test Reference

Complete reference for the smart-test skill — every
check it runs, how gap prioritization works, and how
to act on results. Runs on your Claude subscription —
no API key or additional cost.

## Invocation

```
/smart-test <path>
```

Or natural language:

```
generate tests for src/auth/
what needs testing?
find untested code in src/
write tests for the login module
show me test coverage gaps
```

## The guided flow

The skill uses a Socratic discovery pattern — it asks
questions to scope the work before running. Here's
what to expect:

| Step | What you're asked | Default if skipped |
|------|-------------------|-------------------|
| 1. Target | "Which file or module needs tests?" | Current working directory |
| 2. Approach | "Gap analysis, generate tests, or both?" | Both |

Provide both inline to skip the questions entirely:

```
generate tests for src/auth/
```

## Approaches

| Approach | What it does | Time | Use case |
|----------|-------------|------|----------|
| **Gap analysis** | Scans for untested functions and branches | Seconds | Quick audit before a PR |
| **Generate tests** | Writes pytest tests with edge cases | ~1-2 min | Covering a specific module |
| **Both** | Gaps first, then generates for top gaps | ~2-3 min | Full coverage improvement pass |
| **Batch** | Generates across top N uncovered modules | ~5-10 min | Bootstrapping tests for legacy code |

## All gap types

### Coverage gaps

| Gap type | What it detects | Priority | Example |
|----------|----------------|----------|---------|
| Untested public function | Public API with no matching test | High | `def authenticate()` with 0 tests |
| Zero-coverage branch | if/else path never executed | Medium | `if token_expired:` never true in tests |
| Untested error handler | except block never triggered | High | `except AuthError:` never raised |
| Missing edge case | Boundary value never passed | Medium | Empty string, None, max-length input |
| No parametrized tests | Combinations of inputs never tried | Low | Valid user + expired token |

### Structural gaps

| Gap type | What it detects | Priority | Example |
|----------|----------------|----------|---------|
| No test file exists | Module has zero test file | High | `src/auth/session.py` with no `test_session.py` |
| Stale tests | Tests import deleted functions | Medium | `from auth import old_validate` |
| Partial coverage | Some methods tested, others not | Medium | 3 of 7 public methods have tests |
| Missing fixture | Repeated setup that should be shared | Low | Same 10-line setup in 5 tests |

## Generated test features

Tests generated by smart-test include:

| Feature | What it means | Example |
|---------|--------------|---------|
| **Happy path** | Basic correct-input test | `test_authenticate_valid_credentials()` |
| **Edge cases** | Boundary and unusual inputs | `test_authenticate_empty_password()` |
| **Error paths** | Expected exception tests | `test_authenticate_expired_token_raises()` |
| **Parametrized** | Multiple inputs in one test | `@pytest.mark.parametrize("role", ["admin", "user", "guest"])` |
| **Descriptive names** | What it tests is obvious | `test_validate_token_returns_false_when_expired` |
| **Docstrings** | Google-style test docstrings | `"""Test that expired tokens are rejected."""` |
| **Fixtures** | pytest fixtures for setup | `@pytest.fixture def mock_session():` |

## Output format

### Gap analysis

```markdown
## Test Gap Analysis

**Coverage:** 62% | **Untested Functions:** 14 | **Risk Score:** 7.2/10

### Gaps by Priority

| File | Function | Coverage | Risk | Why |
|------|----------|----------|------|-----|
| [session.py:23](src/auth/session.py#L23) | validate_token() | 0% | High | Auth path, no tests |
| [login.py:45](src/auth/login.py#L45) | authenticate() | 0% | High | 3 branches uncovered |
| [webhook.py:12](src/api/webhook.py#L12) | process_event() | 0% | High | Error path untested |
| [config.py:78](src/config.py#L78) | load_from_env() | 40% | Medium | else branch missing |
| [cache.py:91](src/cache.py#L91) | evict() | 55% | Medium | Empty-cache edge case |
```

### Generated tests

```markdown
## Generated Tests

**Files Created:** 3 | **Tests:** 18 | **Edge Cases:** 12

### tests/test_session.py (6 tests)

| Test | Type | What it covers |
|------|------|----------------|
| test_validate_token_valid | Happy path | Returns True for valid token |
| test_validate_token_expired | Edge case | Returns False when expired |
| test_validate_token_none | Edge case | Handles None input |
| test_validate_token_malformed_raises | Error path | Raises ValueError |
| test_validate_token_empty_string | Edge case | Handles empty string |
| test_validate_token_parametrized | Parametrized | 4 token formats |
```

File links are clickable — click to jump directly to
the gap or generated test.

## Gap prioritization

Gaps are ranked by a risk score that combines several
factors:

| Factor | Weight | Logic |
|--------|--------|-------|
| Function visibility | High | Public > private |
| Code complexity | Medium | More branches = higher risk |
| Error handling | High | Untested except blocks rank higher |
| Recent changes | Medium | Recently modified code ranks higher |
| Dependency count | Low | More callers = higher impact |

| Risk level | Score | Meaning | Typical action |
|------------|-------|---------|----------------|
| Critical | 8-10 | Core path with zero tests | Generate tests immediately |
| High | 6-7.9 | Public API partially tested | Add missing edge cases |
| Medium | 3-5.9 | Internal code with some gaps | Add to sprint backlog |
| Low | 0-2.9 | Minor gaps, low impact | Address when convenient |

## After running

You'll be offered follow-up options based on what was
found:

| Goal | What to say | When it's offered |
|------|-------------|-------------------|
| Generate tests for gaps | "write tests for those gaps" | After gap analysis |
| Run generated tests | "run the tests to verify" | After test generation |
| Check a different module | "now check src/api/" | Always |
| See updated coverage | "show me coverage now" | After generating tests |
| Review code quality | "review the tested files" | Always |
| Fix failing generated tests | "fix the failing tests" | When generated tests fail |
| Export gap report | "export as markdown" | Always |

## Configuration

Smart-test respects your project's existing test setup:

| Setting | How it's detected | Override |
|---------|------------------|----------|
| Test directory | `tests/` or alongside source | Specify path explicitly |
| pytest config | `pyproject.toml` or `pytest.ini` | N/A — uses your config |
| Coverage threshold | 80% default | "use 90% threshold" |
| Naming convention | `test_<module>.py` | Follows existing pattern |

## Want to learn more?

- Say **"what is smart test?"** to go back to the
  overview
- Say **"how do I run smart test?"** for the
  step-by-step guide
- Say **"review src/"** to run a code quality review
- Say **"scan for vulnerabilities"** for security
  analysis
