Skip to content

Commit 0ddc7e8

Browse files
Docs: Add App Router Testing Guides and update /examples (#59268)
This PR updates the testing guides to use App Router and TypeScript, also updates `/examples` to show `app` and `pages` examples. ## Overview - [x] Create a new "Testing" section that is shared between `app` and `pages`. - [x] Explain the differences between E2E, unit testing, component testing, etc. - [x] Recommend E2E for `async` components as currently none of the tools support it. - [x] Update setup guides for **Cypress**, **Playwright**, and **Jest** with latest config options, and examples for `app` and `pages`. - [x] Add new guide for **Vitest** - [x] Clean up `/examples`: use TS, show `app` and `pages` examples, match docs config ## Cypress - [x] E2E Tests - [x] Component Testing - [x] Client Components - [x] Server Components - [ ] `async` components **Blockers:** - TS: `Option 'bundler' can only be used when 'module' is set to 'es2015' or later`. In **tsconfig.json** compilerOptions, Next.js uses "moduleResolution": "bundler", changing it to "node" fixes the issue but it can have repercussions. - cypress-io/cypress#27731 - Version 14 is currently not supported for component testing - cypress-io/cypress#28185 ## Playwright - [x] E2E Tests ## Jest - [x] Unit Testing - [x] Client Components - [x] Server Components - [ ] `async` components: testing-library/react-testing-library#1209 - [x] 'server-only': #54891 - [x] Snapshot Testing **Blockers:** - TS: testing-library/jest-dom#546 - None of the solutions in the issue work with Next.js v14.0.4 and TS v5 ## Vitest - [x] Unit Testing - [x] Client Components - [x] Server Components - [ ] `async` components - [x] 'server-only' - [x] Update vitest example - [x] Handles CSS, and CSS modules imports - [x] Handles next/image ## Other - #47448 - #47299
1 parent 32759b4 commit 0ddc7e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1279
-639
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
title: Setting up Vitest with Next.js
3+
nav: Vitest
4+
description: Learn how to set up Vitest with Next.js for Unit Testing.
5+
---
6+
7+
Vite and React Testing Library are frequently used together for **Unit Testing**. This guide will show you how to setup Vitest with Next.js and write your first tests.
8+
9+
> **Good to know:** Since `async` Server Components are new to the React ecosystem, Vitest currently does not support them. While you can still run **unit tests** for synchronous Server and Client Components, we recommend using an **E2E tests** for `async` components.
10+
11+
## Quickstart
12+
13+
You can use `create-next-app` with the Next.js [with-vitest](https://github.com/vercel/next.js/tree/canary/examples/with-jest) example to quickly get started:
14+
15+
```bash filename="Terminal"
16+
npx create-next-app@latest --example with-vitest with-jest-vitest
17+
```
18+
19+
## Manual Setup
20+
21+
To manually set up Vitest, install `vitest` and the following packages as dev dependencies:
22+
23+
```bash filename="Terminal"
24+
npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react
25+
# or
26+
yarn add -D vitest @vitejs/plugin-react jsdom @testing-library/react @vitejs/plugin-react
27+
# or
28+
pnpm install -D vitest @vitejs/plugin-react jsdom @testing-library/react
29+
```
30+
31+
Create a `vitest.config.ts|js` file in the root of your project, and add the following options:
32+
33+
```ts filename="vitest.config.ts" switcher
34+
import { defineConfig } from 'vitest/config'
35+
import react from '@vitejs/plugin-react'
36+
37+
export default defineConfig({
38+
plugins: [react()],
39+
test: {
40+
environment: 'jsdom',
41+
},
42+
})
43+
```
44+
45+
```js filename="vitest.config.js" switcher
46+
import { defineConfig } from 'vitest/config'
47+
import react from '@vitejs/plugin-react'
48+
49+
export default defineConfig({
50+
plugins: [react()],
51+
test: {
52+
environment: 'jsdom',
53+
},
54+
})
55+
```
56+
57+
For more information on configuring Vitest, please refer to the [Vitest Cofiguration](https://vitest.dev/config/#configuration) docs.
58+
59+
Then, add a `test` script to your `package.json`:
60+
61+
```json filename="package.json"
62+
{
63+
"scripts": {
64+
"dev": "next dev",
65+
"build": "next build",
66+
"start": "next start",
67+
"test": "vitest"
68+
}
69+
}
70+
```
71+
72+
When you run `npm run test`, Vitest will **watch** for changes in your project by default.
73+
74+
## Creating your first Vitest Unit Test
75+
76+
Check that everything is working by creating a test to check if the `<Page />` component successfully renders a heading:
77+
78+
<AppOnly>
79+
80+
```tsx filename="app/page.tsx" switcher
81+
import Link from 'next/link'
82+
83+
export default function Page() {
84+
return (
85+
<div>
86+
<h1>Home</h1>
87+
<Link href="/about">About</Link>
88+
</div>
89+
)
90+
}
91+
```
92+
93+
```jsx filename="app/page.js" switcher
94+
import Link from 'next/link'
95+
96+
export default function Page() {
97+
return (
98+
<div>
99+
<h1>Home</h1>
100+
<Link href="/about">About</Link>
101+
</div>
102+
)
103+
}
104+
```
105+
106+
```tsx filename="__tests__/page.test.tsx" switcher
107+
import { expect, test } from 'vitest'
108+
import { render, screen } from '@testing-library/react'
109+
import Page from '../app/page'
110+
111+
test('Page', () => {
112+
render(<Page />)
113+
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined()
114+
})
115+
```
116+
117+
```jsx filename="__tests__/page.test.jsx" switcher
118+
import { expect, test } from 'vitest'
119+
import { render, screen } from '@testing-library/react'
120+
import Page from '../app/page'
121+
122+
test('Page', () => {
123+
render(<Page />)
124+
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined()
125+
})
126+
```
127+
128+
> **Good to know**: The example above uses the common `__tests__` convention, but test files can also be colocated inside the `app` router.
129+
130+
</AppOnly>
131+
132+
<PagesOnly>
133+
134+
```tsx filename="pages/index.tsx" switcher
135+
import Link from 'next/link'
136+
137+
export default function Page() {
138+
return (
139+
<div>
140+
<h1>Home</h1>
141+
<Link href="/about">About</Link>
142+
</div>
143+
)
144+
}
145+
```
146+
147+
```jsx filename="pages/index.jsx" switcher
148+
import Link from 'next/link'
149+
150+
export default function Page() {
151+
return (
152+
<div>
153+
<h1>Home</h1>
154+
<Link href="/about">About</Link>
155+
</div>
156+
)
157+
}
158+
```
159+
160+
```tsx filename="__tests__/index.test.tsx" switcher
161+
import { expect, test } from 'vitest'
162+
import { render, screen } from '@testing-library/react'
163+
import Page from '../pages/index'
164+
165+
test('Page', () => {
166+
render(<Page />)
167+
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined()
168+
})
169+
```
170+
171+
```jsx filename="__tests__/index.test.jsx" switcher
172+
import { expect, test } from 'vitest'
173+
import { render, screen } from '@testing-library/react'
174+
import Page from '../pages/index'
175+
176+
test('Page', () => {
177+
render(<Page />)
178+
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined()
179+
})
180+
```
181+
182+
</PagesOnly>
183+
184+
## Running your tests
185+
186+
Then, run the following command to run your tests:
187+
188+
```bash filename="Terminal"
189+
npm run test
190+
# or
191+
yarn test
192+
# or
193+
pnpm test
194+
```
195+
196+
## Additional Resources
197+
198+
You may find these resources helpful:
199+
200+
- [Next.js with Vitest example](https://github.com/vercel/next.js/tree/canary/examples/with-vitest)
201+
- [Vitest Docs](https://vitest.dev/guide/)
202+
- [React Testing Library Docs](https://testing-library.com/docs/react-testing-library/intro/)

0 commit comments

Comments
 (0)