Closed13
Next.js にテストを導入する

公式のドキュメントを読みながら導入してみる

- Cypress
- Jest and React Testing Library
の2つある

今欲しいのは Unit Test なので Jest and React Testing Library
を導入する

Jest
使ったこともある
関数やクラスなどテスト用
React Testing Library
使ったこと無い
おそらく react コンポーネントをテストするツール?

Quick Start
公式にサンプルが用意されている
npx create-next-app --example with-jest with-jest-app
Manual setup
既存に導入するときはこっちなので、今回はこっちを叩く
npm install --save-dev jest babel-jest @testing-library/react @testing-library/jest-dom identity-obj-proxy react-test-renderer

Configuring Jest
jest.config.js
module.exports = {
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
],
moduleNameMapper: {
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
'^.+\\.(jpg|jpeg|png|gif|webp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
},
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
},
transformIgnorePatterns: [
'/node_modules/',
'^.+\\.module\\.(css|sass|scss)$',
],
}
collectCoverageFrom
カバレッジの設定
moduleNameMapper
CSS モジュールや画像などをモックする
testPathIgnorePatterns
テストを無視するパス
transform
babel を使う設定
transformIgnorePatterns
transform しないパス

CSS や画像のモック
CSS や画像はテストに使わないが、インポートされるとエラーになる可能性があるのでモックを作る
__mocks__/fileMock.js
(module.exports = "test-file-stub")
__mocks__/styleMock.js
module.exports = {};

カスタムマッチ
Jest には便利なカスタムマッチの機能がある
下記のように設定する
jest.config.js
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
jest.setup.js
import '@testing-library/jest-dom/extend-expect'
今回は一旦設定しない

Absolute Imports and Module Path Aliases
もし、絶対パスの指定をしているのであれば、Jest に設定を書く必要がある
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/components/*": ["components/*"]
}
}
}
jest.config.js
moduleNameMapper: {
'^@/components/(.*)$': '<rootDir>/components/$1',
}
導入しようとしている Next.js のプロジェクトは設定をしているので設定を追加

スクリプトの追加
package.json
"scripts": {
"test": "jest --watch"
}

テストの作成
lib/util/zeroFill.ts
export const zeroFill = (val: number): string => {
return (`0${val}`).slice(-2);
};
lib/util/__tests__/zeroFill.spec.ts
import { zeroFill } from '../zeroFill';
describe('zeroFill', () => {
it('1桁', () => {
expect(zeroFill(1)).toEqual('01');
});
it('2桁', () => {
expect(zeroFill(11)).toEqual('11');
});
});
ESLint に 'describe' is not defined.
, 'it' is not defined.
, 'expect' is not defined.
と怒られる
eslint-plugin-jest
を導入する
npm install --save-dev eslint-plugin-jest
設定を追加し完了
.eslintrc.js
{
"env": {
"jest/globals": true
},
"plugins": ["jest"]
}
npm run test
で無事成功
PASS lib/util/__tests__/zeroFill.spec.ts
zeroFill
✓ 1桁 (2 ms)
✓ 2桁
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.224 s, estimated 2 s
Ran all test suites related to changed files.
Watch Usage: Press w to show more.

カバレッジ
package.json
"scripts": {
"test:coverage": "jest --coverage"
}
実行すると .next
, coverage
, public
配下も見ているので無視する設定を追加
jest.config.js
collectCoverageFrom: [
'!**/.next/**',
'!**/coverage/**',
'!**/public/**',
],

CI
GitHub Actions で動かしたい
を参考に GitHub Actions を作成
.github/workflows/ci.yml
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: NPM Install
run: npm install
- name: Run Test
run: npm run test
このスクラップは2021/08/29にクローズされました