はじめに
ReactのテストをVitestで書いているときに想定の2倍DOMがレンダリングされていました。
問題
<body>
<div>
<div>
<input
placeholder="タイトル"
value=""
/>
<button>
追加
</button>
</div>
<div>
<div>
<p>
勉強
</p>
<input
type="checkbox"
/>
<button>
削除
</button>
</div>
<div>
<p>
洗濯
</p>
<input
type="checkbox"
/>
<button>
削除
</button>
</div>
</div>
</div>
<div>
<div>
<input
placeholder="タイトル"
value=""
/>
<button>
追加
</button>
</div>
<div>
<div>
<p>
勉強
</p>
<input
type="checkbox"
/>
<button>
削除
</button>
</div>
<div>
<p>
洗濯
</p>
<input
type="checkbox"
/>
<button>
削除
</button>
</div>
</div>
</div>
</body>
元のコード
import { beforeEach, describe, expect, test, vi } from "vitest";
import { render } from "@testing-library/react";
beforeEach(() => {
render(<App />);
});
describe("テスト1", () => {
// test
});
describe("テスト2", () => {
// test
});
解決方法1
毎テスト後にDOMをcleanupするようにしました。
修正後のコード
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import { cleanup, render } from "@testing-library/react";
beforeEach(() => {
render(<App />);
});
afterEach(cleanup);
describe("テスト1", () => {
// test
});
describe("テスト2", () => {
// test
});
テストするごとにbeforeEach内の処理が実行され、それが溜まっていました。
解決方法2
解決方法1とは別の方法でも解決できました。
Vitestのテスト用関数をグローバルに公開します。
import react from "@vitejs/plugin-react";
import { defineConfig } from "vitest/config";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
test: {
environment: "jsdom",
globals: true,
},
});
本来、@testing-library/reactは自動的にcleanupをしてくれますが、グローバルにafterEach関数がないためにその処理が実行されていませんでした。
なのでグローバルに設定すれば解決方法1でやったようなafterEachの記述はいりません。
公式ドキュメントから引用
This is called automatically if your testing framework (such as mocha, Jest or Jasmine) injects a global afterEach() function into the testing environment. If not, you will need to call cleanup() after each test.
参考文献
おわりに
やっぱりフロントエンドのテスト難しい
