nextjs-testing
/nextjs-testing
Konfiguruje i pisze testy dla Next.js App Router: Vitest z React Testing Library dla komponentów i logiki serwerowej oraz Playwright dla przepływów end-to-end.
- Autor
- autohandai ↗
- Repozytorium
- skillpack-nextjs-app-router ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 19.10.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 1
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 2
Brak sygnałów. Repozytorium zmienione 19.10.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
Co robi i kiedy
Konfiguruje i pisze testy dla Next.js App Router: Vitest z React Testing Library dla komponentów i logiki serwerowej oraz Playwright dla przepływów end-to-end.
Oryginalny opis (EN)
Sets up and writes tests for a Next.js App Router project, with Vitest and React Testing Library for components and server logic, and Playwright for end-to-end flows including async Server Components. Use when adding test tooling to a Next.js app, writing tests for a new page, form or Server Action, or deciding which layer a test belongs in.
Jak działa
- Pick the layer first
- Vitest setup
- Component test
- Server Action test
- Playwright setup
- Checks before you finish
Podgląd SKILL.md
---
name: nextjs-testing
description: Sets up and writes tests for a Next.js App Router project, with Vitest and React Testing Library for components and server logic, and Playwright for end-to-end flows including async Server Components. Use when adding test tooling to a Next.js app, writing tests for a new page, form or Server Action, or deciding which layer a test belongs in.
license: MIT
---
# Testing a Next.js App Router project
## Pick the layer first
| What you are testing | Tool | Why |
|---|---|---|
| Pure functions, schemas, data helpers | Vitest | Fast, no DOM |
| Client Components and synchronous Server Components | Vitest with jsdom and Testing Library | Renders in memory |
| Server Action logic (validation, auth branches) | Vitest, with `next/*` modules mocked | The function is plain async code |
| Async Server Components, routing, caching, redirects, full forms | Playwright | Vitest can't render async Server Components |
If a test needs a real request, cookies or a redirect, write it in Playwright. Don't mock your way around the framework.
## Vitest setup
```bash
npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom vite-tsconfig-paths
```
```ts
// vitest.config.mts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [tsconfigPaths(), react()],
test: {
environment: 'jsdom',
exclude: ['e2e/**', 'node_modules/**'],
},
})
```
Add `"test": "vitest"` to `package.json` scripts. Drop `vite-tsconfig-paths` in a JavaScript project.
## Component test
```tsx
// app/posts/new/post-form.test.tsx
import { render, screen } from '@testing-library/react'
import { expect, test, vi } from 'vitest'
vi.mock('../actions', () => ({ createPost: vi.fn() }))
import { PostForm } from './post-form'
test('renders the title field and save button', () => {
render(<PostForm />)
expect(screen.getByRole('textbox', { name: /title/i })).toBeDefined()
expect(screen.getByRole('button', { name: 'Save' })).toBeDefined()
})
```
Query by role and accessible name. If a query fails because a field has no label, fix the markup.
## Server Action test
Mock what only exists inside a Next.js request.
```ts
// app/posts/actions.test.ts
import { beforeEach, expect, test, vi } from 'vitest'
vi.mock('next/cache', () => ({ revalidatePath: vi.fn() }))
vi.mock('next/navigation', () => ({
redirect: vi.fn(() => { throw new Error('NEXT_REDIRECT') }),
}))
vi.mock('@/lib/auth', () => ({ auth: vi.fn() }))
vi.mock('@/lib/db', () => ({ db: { post: { create: vi.fn() } } }))
import { createPost } from './actions'
import { auth } from '@/lib/auth'
import { db } from '@/lib/db'
beforeEach(() => vi.clearAllMocks())
function form(fields: Record<string, string>) {
const fd = new FormData()
for (const [k, v] of Object.entries(fields)) fd.set(k, v)
return fd
}
test('rejects an empty title without writing', async () => {
vi.mocked(auth).mockResolvedValue({ user: { id: 'u1' } } as any)
const state = await createPost({}, form({ title: '', body: 'x' }))
expect(state.errors?.title).toBeDefined()
expect(db.post.create).not.toHaveBeenCalled()
})
test('refuses anonymous users', async () => {
vi.mocked(auth).mockResolvedValue(null as any)
const state = await createPost({}, form({ title: 'a', body: 'b' }))
expect(state.message).toMatch(/sign in/i)
expect(db.post.create).not.toHaveBeenCalled()
})
```
Every action should have one test per guard: unauthenticated, unauthorized, invalid input, and success.
## Playwright setup
```bash
npm init playwright@latest
```
```ts
// playwright.config.ts
import { defineConfig } from '@playwright/test'
export default defineConfig({
testDir: './e2e',
use: { baseURL: 'http://localhost:3000' },
webServer: {
command: 'npm run build && npm run start',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 180_000,
},
})
```
Test against a production build. The dev server compiles on demand and hides caching behaviour.
```ts
// e2e/posts.spec.ts
import { test, expect } from '@playwright/test'
test('a signed in user can publish a post', async ({ page }) => {
await page.goto('/posts/new')
await page.getByRole('textbox', { name: 'Title' }).fill('Hello')
await page.getByRole('textbox', { name: 'Body' }).fill('First post')
await page.getByRole('button', { name: 'Save' }).click()
await expect(page).toHaveURL(/\/posts\/[\w-]+$/)
await expect(page.getByRole('heading', { name: 'Hello' })).toBeVisible()
})
```
For signed in flows, log in once in a setup project and reuse `storageState`, rather than logging in for every test.
## Checks before you finish
- `npx vitest run` and `npx playwright test` both pass locally.
- Vitest doesn't pick up `e2e/` specs, and Playwright doesn't pick up `*.test.tsx`.
- No test renders an async Server Component with Testing Library.
- Each Server Action has tests for its auth and validation branches.
- Playwright assertions use web-first `expect(locator)` matchers, not fixed waits.
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · autohandai/skillpack-nextjs-app-router | 100 | MIT |
| aratkruglik/claude-sdlc | 100 | MIT |
| HoangNguyen0403/agent-skills-standard | 100 | MIT |
| jyotiraditya-chauhan/test-kit | 100 | MIT |
Migawka bazy z 28.10.2026 · wersja paczki 7a8f7f2da1f9 (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100testing-react
Pisze testy komponentów, hooków i utilities w React i TypeScript przy użyciu Vitest oraz React Testing Library. - 100react-testing
Testuje komponenty React z React Testing Library oraz Jest lub Vitest. - 100test-ts
Pisze, recenzuje i uruchamia testy TypeScript i React w projekcie Next.js 16 App Router z Vitest, React Testing Library v16, zapytaniami dostępności i user-event. - 100react-testing
Opisuje wzorce testowania komponentów React: komponenty, hooki, kontekst i formularze, z Vitest Browser Mode, vitest-browser-react i @testing-library/react. - 100react-testing
Opisuje testowanie komponentów React z Testing Library i Vitest: testy jednostkowe i integracyjne, asynchroniczne, mockowanie, zdarzenia użytkownika i dostępność. - 100react-testing
Opisuje testowanie komponentów React z React Testing Library, Vitest lub Jest, MSW, asercjami dostępności z axe oraz granicą między testami komponentów a E2E w Playwright i Cypress.