Closed10
【key-front】react-testing-libraryの素振りをしてみた(後編)
モチベーション
- 毎週木曜日Slackのkey_frontチャンネルでハドル機能を使いお題に対してメンバー同士ディスカッションをする時間を15〜30分程度設けている
- 今回は「react-testing-libraryを触ってみて(前編)」の後編を共有する
- ファシリテーターは筆者なので、事前に読み込んで気になった点などをスクラップに投げていく
- 開催日は10/26(木)で最終的に議事録として結論をまとめる
前編
jestにエイリアスを追加する
記事を参考にjestにもエイリアスを追加する。jestはVite経由で実行されないのが原因ぽい。
jest.config.json
{
"roots": ["<rootDir>/resources/js"],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"testEnvironment": "jest-environment-jsdom",
"setupFilesAfterEnv": ["<rootDir>/jest.setup.ts"],
"moduleNameMapper": {
"^@/(.*)$": "<rootDir>/resources/js/$1" // 追加する
}
}
import { render, screen } from '@testing-library/react'
import Test from '@/pages/Test' // エイリアスが有効になっている
describe('get by text', () => {
it('get by text', () => {
render(<Test />)
const element = screen.getByText('Hello')
expect(element).toBeInTheDocument()
})
})
参考記事
Viteのimport.metaでエラーが発生する
記事を参考にprocess.env.〇〇のアクセスに切り替える
// NG
const { PROD } = import.meta.env // error
// OK
process.env.NODE_ENV // "development" or "production" or "test"
参考記事
MUIコンポーネントのユニットテストをする
paletteを使っている場合(Providerを使用している場合)は下記のように改修する必要がある
import { ThemeProvider } from '@mui/material/styles'
import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from '@/components/uis/Button'
import { theme } from '@/functions/libs'
describe('Buttonコンポーネントのテスト', () => {
it('正しくレンダリングされる', () => {
render(
<ThemeProvider theme={theme}> // 追加する
<Button>Test</Button>
</ThemeProvider>
)
const buttonElement = screen.getByRole('button')
expect(buttonElement).toBeInTheDocument()
})
})
参考記事
しかし、このままだとテストを作るたびにButtonコンポーネントにProviderをラップさせる必要がある。記事を参考にrender関数をオーバーライドさせる。
import { render, screen, fireEvent } from '@/__tests__/utilities/test-utils'
import { Button } from '@/components/uis/Button'
describe('Buttonコンポーネントのテスト', () => {
it('正しくレンダリングされる', () => {
render(<Button>Test</Button>)
const buttonElement = screen.getByRole('button')
expect(buttonElement).toBeInTheDocument()
})
})
参考記事
特定のディレクトリをignoreする
先ほど作ったcustom-renderをテストの対象外にする
jest.config.json
module.exports = {
"testPathIgnorePatterns": ["<rootDir>/resources/js/__tests__/utilities"],
}
SVGファイルを読み込めるようにする
記事を参考に実装する。jest-svg-transformerとかライブラリは使わなくてok。
fileTransformer.js
const path = require('path');
module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
jest.config.json
module.exports = {
"transform": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
},
}
VSCodeの拡張機能
- 特定のテストはjest runner
- 全てのテストはnpm run test
更新済み
リンターの導入
READMEの通りに実装すればok
userEventをcustomRenderに組み込む
下記を多用するのでどうにかしたい
import userEvent from '@testing-library/user-event'
const user = userEvent.setup()
ドキュメントを見るとrenderに組み込む実装が案内されているので、先ほどのcustomRenderに組み込む
import { ThemeProvider } from '@mui/material/styles'
import { render, RenderOptions } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { theme } from '@/functions/libs'
const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
return <ThemeProvider theme={theme}>{children}</ThemeProvider>
}
const customRender = (
ui: React.ReactElement,
options?: Omit<RenderOptions, 'wrapper'>
) => {
return {
user: userEvent.setup(),
...render(ui, { wrapper: AllTheProviders, ...options })
}
}
// re-export everything
export * from '@testing-library/react'
// override render method
export { customRender as render }
補足
次の記事が全く考えで同じことを実装していたのでメモ
補足内容としてはuserEventがv14から実装が微妙に異なる。react-testing-libraryに関する記事も古いものが見受けられるので注意。
import userEvent from '@testing-library/user-event';
// v14以前
userEvent.click(button);
// v14移行
const user = userEvent.setup();
await user.click(button);
さらに補足
RTLではfireEventよりuserEventを使った方が良いメモ
議事録_20231026
- 10/26(木)に実施
- 参加人数は11名(以下エビデンス)
- 4ヶ月続けて初の参加者10人越えだったので素直に嬉しかった。
- テスト経験者は3名ほどしかいなくどうしても受託会社という側面があるので、テストより実装を優先して欲しいと先方から言われることがある
- そもそもフロントのリソースが足りなくテストまで余力がない
- 案件によってはテストを実施しているものもあるので一概にテストを軽視しているわけではない
- 結論としては品質の良いものを納品する=テストで品質担保は直結するので基盤開発周りのテンプレートを作って実装までのショートカットを作れば良いのではという形に落ち着いた
TODO
- Reactでテストをするための技術選定を行う
- テストのテンプレートを作る
このスクラップは2023/10/26にクローズされました