Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOCS] Update testing docs #28064

Merged
merged 2 commits into from Aug 13, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
248 changes: 125 additions & 123 deletions docs/testing.md
Expand Up @@ -3,12 +3,134 @@
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-jest">Next.js with Jest and React Testing Library</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-cypress">Next.js with Cypress</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-jest">Next.js with Jest and React Testing Library</a></li>
</ul>
</details>

Learn how to set up Next.js with three commonly used testing tools: [Jest](https://jestjs.io/docs/tutorial-react), [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/), and [Cypress](https://www.cypress.io/blog/2021/04/06/cypress-component-testing-react/).
Learn how to set up Next.js with three commonly used testing tools: [Cypress](https://www.cypress.io/blog/2021/04/06/cypress-component-testing-react/), [Jest](https://jestjs.io/docs/tutorial-react), and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/).

## Cypress

Cypress is a test runner used for **End-to-End (E2E)** and **Integration Testing**.

### Quickstart

You can use `create-next-app` with the [with-cypress example](https://github.com/vercel/next.js/tree/canary/examples/with-jest) to quickly get started.

```bash
npx create-next-app --example with-cypress with-cypress-app
```

### Manual setup

To get started with Cypress, install the `cypress` package:

```bash
npm install --save-dev cypress
```

Add Cypress to the `package.json` scripts field:

```json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"cypress": "cypress open",
}
```

Run Cypress for the first time to generate examples that use their recommended folder structure:

```bash
npm run cypress
```

You can look through the generated examples and the [Writing Your First Test](https://docs.cypress.io/guides/getting-started/writing-your-first-test) section of the Cypress Documentation to help you get familiar with Cypress.

### Creating your first Cypress integration test

Assuming the following two Next.js pages:

```jsx
// pages/index.js
import Link from 'next/link'

export default function Home() {
return (
<nav>
<Link href="/about">
<a>About</a>
</Link>
</nav>
)
}
```

```jsx
// pages/about.js
export default function About() {
return (
<div>
<h1>About Page</h1>
</div>
)
}
```

Add a test to check your navigation is working correctly:

```jsx
// cypress/integration/app.spec.js

describe('Navigation', () => {
it('should navigate to the about page', () => {
// Start from the index page
cy.visit('http://localhost:3000/')

// Find a link with an href attribute containing "about" and click it
cy.get('a[href*="about"]').click()

// The new url should include "/about"
cy.url().should('include', '/about')

// The new page should contain an h1 with "About page"
cy.get('h1').contains('About Page')
})
})
```

You can use `cy.visit("/")` instead of `cy.visit("http://localhost:3000/")` if you add `"baseUrl": "http://localhost:3000"` to the `cypress.json` configuration file.

### Running your Cypress tests

Since Cypress is testing a real Next.js application, it requires the Next.js server to be running prior to starting Cypress. We recommend running your tests against your production code to more closely resemble how your application will behave.

Run `npm run build` and `npm run start`, then run `npm run cypress` in another terminal window to start Cypress.

> **Note:** Alternatively, you can install the `start-server-and-test` package and add it to the `package.json` scripts field: `"test": "start-server-and-test start http://localhost:3000 cypress"` to start the Next.js production server in conjuction with Cypress. Remember to rebuild your application after new changes.

### Getting ready for Continuous Integration (CI)

You will have noticed that running Cypress so far has opened an interactive browser which is not ideal for CI environments. You can also run Cypress headlessly using the `cypress run` command:

```json
// package.json

"scripts": {
//...
"cypress": "cypress open",
"cypress:headless": "cypress run",
"e2e": "start-server-and-test start http://localhost:3000 cypress",
"e2e:headless": "start-server-and-test start http://localhost:3000 cypress:headless"
}
```

You can learn more about Cypress and Continuous Integration from these resources:

- [Cypress Continuous Integration Docs](https://docs.cypress.io/guides/continuous-integration/introduction)
- [Official Cypress Github Action](https://github.com/cypress-io/github-action)

## Jest and React Testing Library

Expand Down Expand Up @@ -185,7 +307,7 @@ it('renders homepage unchanged', () => {
})
```

Test files should not be included inside the pages directory because any files inside the pages directory are considered routes.
> **Note**: Test files should not be included inside the pages directory because any files inside the pages directory are considered routes.

**Running your test suite**

Expand All @@ -197,126 +319,6 @@ For further reading, you may find these resources helpful:
- [React Testing Library Docs](https://testing-library.com/docs/react-testing-library/intro/)
- [Testing Playground](https://testing-playground.com/) - use good testing practices to match elements.

## Cypress

Cypress is a test runner used for **End-to-End (E2E)** and **Integration Testing**.

### Quickstart

You can use `create-next-app` with the [with-cypress example](https://github.com/vercel/next.js/tree/canary/examples/with-jest) to quickly get started.

```bash
npx create-next-app --example with-cypress with-cypress-app
```

### Manual setup

To get started with Cypress, install the `cypress` package:

```bash
npm install --save-dev cypress
```

Add Cypress to the `package.json` scripts field:

```json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"cypress": "cypress open",
}
```

Run Cypress for the first time to generate examples that use their recommended folder structure:

```bash
npm run cypress
```

You can look through the generated examples and the [Writing Your First Test](https://docs.cypress.io/guides/getting-started/writing-your-first-test) section of the Cypress Documentation to help you get familiar with Cypress.

### Creating your first Cypress integration test

Assuming the following two Next.js pages:

```jsx
// pages/index.js
import Link from 'next/link'

export default function Home() {
return (
<nav>
<Link href="/about">
<a>About</a>
</Link>
</nav>
)
}
```

```jsx
// pages/about.js
export default function About() {
return (
<div>
<h1>About Page</h1>
</div>
)
}
```

Add a test to check your navigation is working correctly:

```jsx
// cypress/integration/app.spec.js

describe('Navigation', () => {
it('should navigate to the about page', () => {
// Start from the index page
cy.visit('http://localhost:3000/')

// Find a link with an href attribute containing "about" and click it
cy.get('a[href*="about"]').click()

// The new url should include "/about"
cy.url().should('include', '/about')

// The new page should contain an h1 with "About page"
cy.get('h1').contains('About Page')
})
})
```

You can use `cy.visit("/")` instead of `cy.visit("http://localhost:3000/")` if you add `"baseUrl": "http://localhost:3000"` to the `cypress.json` configuration file.

### Running your Cypress tests

Because Cypress is testing a real Next.js application, it requires the Next.js server to be running prior to starting Cypress. Run `npm run dev` to start the development server then run `npm run cypress` in another terminal window to start Cypress.

Alternatively, you can install the `start-server-and-test` package and add it to the `package.json` scripts field: `"test": "start-server-and-test dev http://localhost:3000 cypress"` to start the Next.js development server when you run Cypress.

### Getting ready for Continuous Integration (CI)

You will have noticed that running Cypress so far has opened an interactive browser which is not ideal for CI environments. You can also run Cypress headlessly using the `cypress run` command:

```json
// package.json

"scripts": {
//...
"cypress": "cypress open",
"cypress:headless": "cypress run",
"e2e": "start-server-and-test dev http://localhost:3000 cypress",
"e2e:headless": "start-server-and-test dev http://localhost:3000 cypress:headless"
}
```

You can learn more about Cypress and Continuous Integration from these resources:

- [Cypress Continuous Integration Docs](https://docs.cypress.io/guides/continuous-integration/introduction)
- [Official Cypress Github Action](https://github.com/cypress-io/github-action)

## Community Packages and Examples

The Next.js community has created packages and articles you may find helpful:
Expand Down