CursorIntermediate

How to Generate and Maintain Tests with Cursor Composer

Have Composer write a test file for a module and update it across files when the implementation changes.

8 minIntermediate

Composer is good at writing tests because it can read the implementation, the existing test setup, and your conventions all at once. Better still, when you later change the implementation, it can update the test file in the same pass. This guide creates a test file for a module and then keeps it in sync after a signature change.

  • A test runner already configured (Jest, Vitest, or similar)
  • A module you want covered
  • One existing test file Composer can copy the style from

Give Composer the module and a sample test

Add both the module under test and one existing test file with @. The sample test teaches Composer your import paths, assertion style, and naming so the new tests match the rest of the suite.

Composer prompt
@src/lib/price.ts @src/lib/tax.test.ts
Write a test file for price.ts following the style of tax.test.ts.
Cover the happy path, a zero quantity, and a negative price error.
Composer - New test file
Explorer
price.ts
tax.test.ts
price.test.ts
src/lib/price.test.ts
1import { calcPrice } from './price';
2
3describe('calcPrice', () => {
4 it('multiplies unit price by quantity', () => {
5 expect(calcPrice(10, 3)).toBe(30);
6 });
7});
Composer proposes a new file alongside the module it tests.

Run the new tests

Accept the new file and run the suite. If a generated test fails, that is useful information: either the test is wrong or it found a real bug. Read the failure before assuming the test is at fault.

zsh - run tests
$npm test -- price.test.ts
PASS src/lib/price.test.ts (3 tests)
$

Keep tests in sync after a change

When you change a function signature, ask Composer to update the implementation and its tests together. Because it edits both files in one diff, the tests do not drift out of date.

Composer prompt
calcPrice should take an options object { unit, qty, discount }.
Update price.ts and price.test.ts together. Add a test for discount.
Ask for the cases, not just coverage
Naming the specific cases you want, like zero quantity or a thrown error, produces far more meaningful tests than asking for full coverage in the abstract.

Result: a new test file written in your house style, and a workflow where signature changes update both the code and its tests in a single reviewable diff.

Watch related tutorials

Tags
#cursor#composer#testing#multi-file