One page
Testing cheat sheet
What to keep at hand. If a line is not clear, go back to the matching lesson in the course.
Open the course: Testing: unit, integration, e2eVitest: the essentials
| What | How |
|---|---|
| Group and test | describe("cart", () => { it("sums", () => {}) }) |
| Equality of values and objects | expect(a).toBe(1); expect(obj).toEqual({ a: 1 }) |
| Partial match | expect(res).toMatchObject({ status: 'ok' }) |
| Exception | expect(() => fn()).toThrow(RangeError) |
| Promise rejected | await expect(p).rejects.toThrow('not found') |
| Table test | it.each(cases)("$input", ({ input }) => {}) |
| Run in CI | vitest run |
Test doubles in Vitest
| What | How |
|---|---|
| Empty function with call history | const fn = vi.fn() |
| Canned answer | vi.fn().mockResolvedValue(user) |
| Spy on a method | vi.spyOn(obj, 'send') |
| Check a call | expect(fn).toHaveBeenCalledWith('a', 1) |
| Fake timers | vi.useFakeTimers(); vi.advanceTimersByTime(300) |
| Pin the date | vi.setSystemTime(new Date('2026-01-01')) |
| Network via MSW | setupServer(http.get(url, () => HttpResponse.json({}))) |
Integration tests
| What | How |
|---|---|
| Postgres in Testcontainers | await new PostgreSqlContainer('postgres:17').start() |
| Connection string | container.getConnectionUri() |
| Test isolation | BEGIN in beforeEach, ROLLBACK in afterEach |
| API request | await request(app).post('/users').send(body).expect(201) |
| Any number in a field | expect(res.body.id).toEqual(expect.any(Number)) |
Playwright
| What | How |
|---|---|
| Run and UI mode | pnpm exec playwright test --ui |
| Role locator | page.getByRole('button', { name: 'Save' }) |
| Field by label | page.getByLabel('Email').fill('[email protected]') |
| Web-first assertion | await expect(locator).toBeVisible() |
| Custom fixture | test.extend<{ user: User }>({ user: async ({}, use) => {} }) |
| Replacing the network | await page.route('**/api/pay', (r) => r.fulfill({ json: {} })) |
| Trace for retries | use: { trace: 'on-first-retry' } |