Skip to content

chore(skill): Add skill for writing unit and E2E tests#20561

Merged
s1gr1d merged 4 commits intodevelopfrom
sig/test-skill
Apr 29, 2026
Merged

chore(skill): Add skill for writing unit and E2E tests#20561
s1gr1d merged 4 commits intodevelopfrom
sig/test-skill

Conversation

@s1gr1d
Copy link
Copy Markdown
Member

@s1gr1d s1gr1d commented Apr 28, 2026

Add skill for writing tests. Created and evaluated with https://github.com/anthropics/skills/blob/main/skills/skill-creator/SKILL.md

Used sources for "how to write good tests":

Copy link
Copy Markdown
Member

@JPeer264 JPeer264 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great skill. You think it makes sense to highlight that we have reusable test utils that can be used?

E.g. in the e2e tests nothing is written WHAT to test (like errors, traces, metrics, etc)


### Arrange → Act → Assert

Structure every test with the AAA pattern, separated by blank lines. The whitespace makes the
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: I love this approach and used it a lot. However, does it make sense to separate the phases with whitespaces?

I only know it with strict comments:

# Arrange
// ... some arranging

# Act
// ... some acting

# Assert
// ... expect(false).toBe(true)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to be too explicit about that. AAA is more about the structure of the test, I don't have hard opinions on how the steps are separated.


// Good: asserts on the observable outcome
it('sets transaction name from route path', () => {
responseHandler(createMockContext(200));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: Here there are no whitespaces. Is this now already following the AAA pattern? Not sure if LLMs might get confused already

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm gonna fix that.

Comment thread .agents/skills/write-tests/SKILL.md Outdated
Default to exact matching. `toMatchObject`, `expect.objectContaining`, and `expect.arrayContaining`
silently ignore fields that matter. This has caused real bugs to ship in this codebase.

**Use `toEqual` unless you have a specific reason not to.** The same applies to
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use toEqual unless you have a specific reason not to.

What would be a specific reason not to?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reworded that a bit

Comment thread .agents/skills/write-tests/SKILL.md Outdated

### Boundary Value Analysis

If the valid range is 1–100, test 0, 1, 2, 99, 100, 101. Bugs cluster at boundaries — off-by-one
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the valid range is 1–100, test 0, 1, 2, 99, 100, 101. Bugs cluster at boundaries — off-by-one
If the valid range is 1–100, test -10, 0, 1, 2, 99, 100, 101, Number.POSITIVE_INFINITY. Bugs cluster at boundaries — off-by-one

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also -1

Comment thread .agents/skills/write-tests/SKILL.md Outdated

- Name test files `*.test.ts`, mirroring the source path: `src/shared/patchRoute.ts` →
`test/shared/patchRoute.test.ts`.
- Import from the source path (`../../src/...`), not from the package's published API.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: Shouldn't we import from the published API if there is one? That would also then check for breaking changes in case we would by accident delete something somewhere

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For other packages, yes. But not for the package being tested. I'm gonna make that more clear.

package, prefer the import form for type safety:

```typescript
vi.mock(import('../../src/utils'), async importOriginal => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: I've seen a lot of times that this causes brutal type errors 😅 even though I would prefer it for the sake of type safety

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always fall back. But I added that because vitest recommends it: https://vitest.dev/guide/learn/mock-functions.html#mocking-modules

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes they recommend it and it makes sense, just wanted to highlight that in practice this is often a nightmare to use

Comment thread .agents/skills/write-tests/SKILL.md Outdated

### Grouping

Two levels of `describe` is usually enough. Deeper nesting makes tests harder to find and read.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: It doesn't say if describe is actually needed. Would it be fine if we only have it() as top-level? With nx everything is grouped already so it would be too bad if it is not wrapped in at least one describe()

@s1gr1d
Copy link
Copy Markdown
Member Author

s1gr1d commented Apr 28, 2026

@JPeer264 You think it makes sense to highlight that we have reusable test utils that can be used? E.g. in the e2e tests nothing is written WHAT to test (like errors, traces, metrics, etc)

For that, it's worth splitting this skill into unit-test and E2E test instructions. I could do that in another PR.

@s1gr1d s1gr1d requested a review from JPeer264 April 28, 2026 14:11
@s1gr1d s1gr1d merged commit fae6a7d into develop Apr 29, 2026
34 checks passed
@s1gr1d s1gr1d deleted the sig/test-skill branch April 29, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants