$npx -y skills add dan-the-dev/xp-developer-skills --skill legacy-testingMichael Feathers–style legacy code change — treat code without automated tests as legacy, then follow identify change points, find test points, break dependencies, add tests (often characterization), and only then modify or refactor. Covers seams (object/link/preprocessing), sens
| 1 | # Legacy code testing (Feathers-style) |
| 2 | |
| 3 | ## Mission |
| 4 | |
| 5 | **Legacy code** (Feathers): code **without automated tests** covering the behavior you need to change. Not “old” — **unprotected**. Without tests you cannot know whether a change **helps or harms** the system. |
| 6 | |
| 7 | **Goal:** build a **test harness** and **pin down behavior** so later edits use normal **bugfix**, **TDD**, or **refactoring** skills safely. |
| 8 | |
| 9 | Think: **strap on sensors before opening the engine** — you are not proving virtue first; you are **documenting what happens today** so the next move is reversible and observable. |
| 10 | |
| 11 | Optimize for: |
| 12 | |
| 13 | - **Safety** — never “big bang” into untested internals |
| 14 | - **Seams** — places behavior can vary without editing the legacy core at that line ([references/seams-sensing-separation.md](references/seams-sensing-separation.md)) |
| 15 | - **Characterization** — tests that lock **current** behavior before intentional change ([references/characterization-tests.md](references/characterization-tests.md)) |
| 16 | - **Small steps** — one dependency break or one test at a time; **green** after each meaningful commit ([references/feathers-change-algorithm.md](references/feathers-change-algorithm.md)) |
| 17 | - **Composition** — once the net exists, switch to `skills/tdd`, `skills/refactoring`, `skills/bugfix` as appropriate |
| 18 | |
| 19 | This skill does **not** replace **ATDD** for new capability definition; it often **precedes** confident refactoring. |
| 20 | |
| 21 | --- |
| 22 | |
| 23 | ## Feathers’ change algorithm (five phases) |
| 24 | |
| 25 | Work in order; do not skip “find test points” and “break dependencies” by writing giant integration tests that never fail for the right reason. |
| 26 | |
| 27 | 1. **Identify change points** — where must the code differ after your goal? |
| 28 | 2. **Find test points** — where can you observe or assert behavior cheaply? |
| 29 | 3. **Break dependencies** — make the code **callable / observable** in a test harness (seams, fakes, parameterization). |
| 30 | 4. **Write tests** — usually **characterization** first; add bug-targeted tests if you already know wrong behavior. |
| 31 | 5. **Modify and refactor** — implement; then **refactor** with `skills/refactoring` now that behavior is pinned. |
| 32 | |
| 33 | Detail: [references/feathers-change-algorithm.md](references/feathers-change-algorithm.md). |
| 34 | |
| 35 | --- |
| 36 | |
| 37 | ## Quick techniques (when time is short) |
| 38 | |
| 39 | | Technique | Use when | |
| 40 | |-----------|-----------| |
| 41 | | **Sprout Method / Class** | New logic can live in a new unit; legacy calls into it (minimal surface change). | |
| 42 | | **Wrap Method / Class** | Add behavior **before/after** existing code (often decorator-like); existing core stays untouched at first. | |
| 43 | |
| 44 | See [references/sprout-and-wrap.md](references/sprout-and-wrap.md). |
| 45 | |
| 46 | --- |
| 47 | |
| 48 | ## Core concepts (recap) |
| 49 | |
| 50 | - **Seams** — preprocessing, link, **object** seams — places to substitute behavior for tests ([references/seams-sensing-separation.md](references/seams-sensing-separation.md)). |
| 51 | - **Sensing & separation** — break dependencies to **read** outcomes you couldn’t see, or to **isolate** execution ([references/seams-sensing-separation.md](references/seams-sensing-separation.md)). |
| 52 | - **Characterization tests** — “today’s truth” as executable documentation ([references/characterization-tests.md](references/characterization-tests.md)). |
| 53 | - **Pinch points** — narrow places where a few tests cover many paths ([references/pinch-points-and-effect-sketches.md](references/pinch-points-and-effect-sketches.md)). |
| 54 | - **Effect sketches** — lightweight maps of how a change **ripples** ([references/pinch-points-and-effect-sketches.md](references/pinch-points-and-effect-sketches.md)). |
| 55 | - **Dependency-breaking catalog** — extract interface, subclass & override, parameterize constructor, etc. ([references/dependency-breaking-techniques.md](references/dependency-breaking-techniques.md)). |
| 56 | - **Monsters & libraries** — huge classes/methods, third-party lock-in; wrappers and incremental carving ([references/monsters-and-libraries.md](references/monsters-and-libraries.md)). |
| 57 | |
| 58 | --- |
| 59 | |
| 60 | ## Integration with other discipline (Fowler, Beck, Farley, Cupac) |
| 61 | |
| 62 | - **Kent Beck** — same **tiny verified steps** and **revert** instinct as TDD; legacy work just **pays the debt** to get to RED/GREEN/REFACTOR at useful seams. |
| 63 | - **Martin Fowler** — legacy session often **ends** in **refactoring**; until tests exist, many edits are **seam-finding** and **characterization**, not full ca |