導入から簡単なテストの実施まで。
基本的に下記内容をなぞる。
環境
- Next.js v15
- React v19 → v18
- TypeScript v5
- App Router
Quickstart
$ npx create-next-app@latest --example with-jest with-jest-app
Manual setup
React のバージョンが19以上だとインストール時にエラーが起きるので、
バージョンを18にする必要があった。
--force をつけて強制的にインストールすることもできるけど、
中々に危ないので、バージョンを落とす。
# エラーが出る。
$ npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node
Could not resolve dependency:
peer react@"^18.0.0 || ^19.0.0" from @testing-library/react@16.2.0
Fix the upstream dependency conflict, or retry
this command with --force or --legacy-peer-deps
to accept an incorrect (and potentially broken) dependency resolution.
# Next.js と React をアンインストールする
$ npm uninstall --save next react react-dom
# バージョンを指定してインストールする
$ npm install --save next@latest react@18 react-dom@18
セットアップ
自分が選択した内容。適当。
- yes
- yes
- jsdom
- yes
- v8
- no
$ npm init jest@latest
✔ Would you like to use Jest when running "test" script in "package.json"? … yes
✔ Would you like to use Typescript for the configuration file? … yes
Choose the test environment that will be used for testing › jsdom (browser-like)
✔ Do you want Jest to add coverage reports? … yes
✔ Which provider should be used to instrument code for coverage? › v8
✔ Automatically clear mock calls, instances, contexts and results before every test? … no
jest.config.ts
コード抜粋。
import type { Config } from "jest"
import nextJest from "next/jest.js"
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
})
const config: Config = {
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,
// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
// A list of reporter names that Jest uses when writing coverage reports
coverageReporters: [
// "json",
"text",
"lcov",
// "clover"
],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
// A list of paths to modules that run some code to configure or set up the testing framework before each test
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
// The test environment that will be used for testing
// testEnvironment: "jsdom",
testEnvironment: "./CustomJSDOMEnvironment.ts",
}
export default createJestConfig(config)
jest.setup.ts
jest.config.ts の setupFilesAfterEnv で必要。
import "@testing-library/jest-dom"
CustomJSDOMEnvironment.ts
jest.config.ts の testEnvironment で必要。
import JSDOMEnvironment from "jest-environment-jsdom"
// https://qiita.com/takano-h/items/506fa48493873bf7af41
// https://github.com/jsdom/jsdom/issues/1724#issuecomment-1446858041
// https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string
export default class CustomJSDOMEnvironment extends JSDOMEnvironment {
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
super(...args)
// https://github.com/mswjs/jest-fixed-jsdom/blob/main/index.js
// this.customExportConditions = args.customExportConditions || [""]
this.global.TextDecoder = TextDecoder
this.global.TextEncoder = TextEncoder
this.global.TextDecoderStream = TextDecoderStream
this.global.TextEncoderStream = TextEncoderStream
this.global.ReadableStream = ReadableStream
// FIXME https://github.com/jsdom/jsdom/issues/1724
if (!this.global.fetch) {
this.global.fetch = fetch
this.global.Headers = Headers
this.global.Request = Request
this.global.Response = Response
}
}
}
tsconfig.json
コード抜粋。
jest.config.ts の moduleNameMapper で必要。
{
"compilerOptions": {
"paths": {
"@/*": [
"./src/*"
]
}
}
}
package.json
コード抜粋。
{
"scripts": {
"test": "jest"
}
}
簡単なテストを実施する
テストファイルの置き場所は宗教があるみたい。
一旦内容をなぞる形で進める。
/src/__tests__/test.test.ts
import { describe, expect, test } from "@jest/globals"
function sum(a, b) {
return a + b
}
describe("sum() のテスト", () => {
test("1 + 2 は 3 です", () => {
expect(sum(1, 2)).toBe(3)
})
})
テスト開始
$ npm run test
> sample@0.1.0 test
> jest
(node:17328) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
PASS src/__tests__/test.test.ts
sum() のテスト
✓ 1 + 2 は 3 です (1 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.534 s, estimated 1 s
Ran all test suites.