⚙️
ReactとVue3のVitestと@Storybook/test-runnerの導入比較
会社で以下の記事を参考に、ReactとVueそれぞれのコンポーネントライブラリのstorybookでテストができる環境を作ることになったので、必要なパッケージ、記述の違いといった部分に焦点を当てた記事です。
最終的に目指すもの
-
npm run test
oryarn test
でVitestを走らせる。 -
npm run test-storybook
oryarn test-storybook
でstorybookのtest-runnerを動かす。
パッケージ紹介
- @storybook/test:storybookでテストをする際に使うもので、Vitestで動いている[1]。
- @storybook/test-runner:実行するだけで全てのstoryとplay関数があればそれをテストしてくれる。
- @testing-library/jest-dom:直感的に分かりやすい記述でDOMテストができるようになる。
-
@testing-library/react:全部は把握できていませんが、
render
で簡単にコンポーネントを生成、screen
でdocument.bodyに簡単にアクセス出来る。screenを使うためにはjsdomなどのglobal DOM environmentが必要らしい(把握してない) - @testing-library/vue:↑のVue版
- jsdom:testing-libraryを活用するのに必要
- vitest:これがないと始まらない
package.json
Testing LibraryがReactとVue3で異なるのを除いては共通
Reactの場合
package.jsonから抜粋
{
"devDependencies":{
"@storybook/test": "^8.0.4",
"@storybook/test-runner": "^0.17.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.2",
"@vitest/ui": "^1.5.0",
"jsdom": "^24.0.0",
"vitest": "^1.5.0"
},
}
Vue3の場合
package.jsonから抜粋
{
"devDependencies":{
"@storybook/test": "^8.0.4",
"@storybook/test-runner": "^0.17.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/vue": "^8.0.3",
"@vitest/ui": "^1.5.0",
"jsdom": "^24.0.0",
"vitest": "^1.5.0"
},
}
vite.config.ts
ReactはdefineConfig
のimport元をvitest/config
にすれば良かったですが、vue3の場合はvitest.config.tsなどの別ファイルでmergeConfig
を用いる必要がありました[2]。
Reactの場合
vite.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react-swc';
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
test: {
globals: true,
environment: 'jsdom',
setupFiles: './test/setup.ts',
css: true
}
});
Vue3の場合
vitest.config.ts
import { defineConfig } from "vitest/config";
import { mergeConfig } from "vite";
import viteConfig from "./vite.config";
export default mergeConfig(
viteConfig,
defineConfig({
test: {
globals: true,
environment: "jsdom",
setupFiles: "./test/setup.ts",
css: true,
},
})
);
test.tsx/test.ts
ReactとVue3ではrender
の取り扱いが微妙に異なります。
Reactの場合
button.test.tsx
import { render, screen } from '@testing-library/react';
import { Button } from './button';
test('基本的なレンダリング', () => {
render(<Button>ボタン</Button>); //HTML的な書き方で渡す
expect(screen.getByRole('button')).toHaveTextContent('ボタン');
});
Vue3の場合
button.test.ts
import Button from '../components/Button.vue';
import { render, screen } from '@testing-library/vue';
test('基本的なレンダリング', () => {
render(Button,{
props: {
label: 'ボタン' //コンポーネント、Propsの順で渡す
}
});
expect(screen.getByRole('button')).toHaveTextContent('ボタン');
});
# storybookのtest-runnerはどちらも同じ
Discussion