Vitest Browser Modeがアツい
Background
これまでVitestでコンポーネントのテストを行う時は、jsdom や happy-dom を使ってブラウザ環境を偽装していました。しかし、偽のブラウザ環境を使うことは多くの問題があり、また開発者はテスト以外でどこにも存在しない環境を作り上げるという不毛な作業が必要でした。
この問題を解決するために、Playwright や Cypress などのテストフレームワークは Component Test をサポートしています。しかし、UnitテストでPlaywrightやCypressを使うのは少々Fatであり、Reactのhooksなどのテストをすることができません。
Vitest Browser Modeを使用することで、Vitest上でComponent Testが可能となり、これらの問題を解決できます。
Installation
Browser ModeのSetupは以下を参照してください。
Demo
Radix UIのTooltipを使った以下のコンポーネントに対してテストを書いていきます。
vitestの設定を以下のようにし、拡張子がbrowser.test.tsx
ならBrowser Modeで実行し、jsdom.test.tsx
ならjsdomで実行するようにしています(初めてVitestのWorkspaceを利用しましたが便利)。
jsdomを使った従来のテスト
注目ポイントは6行目のbeforeAllです。Radix UIのTooltipは内部で ResizeObserver を使用していますが、jsdomにはResizeObserverが実装されていません。そのため、以下のようにResizeObserverを簡単にmockしています。
このようにjsdomに実装されていないWeb APIは自分でmockをしたり、polyfillを差し込んだりする必要があります。
また以下のようなsetupFileが必要で、環境構築をする際に大体の人はつまづくポイントだと思います。
Browser Modeを使ったテスト
Browser Modeでは上記のコードが何の設定もなしに動作します(手軽!)。
また、テスト実行時にはテスト対象のコンポーネントを実際にブラウザ上で確認することができます。
ブラウザ上でテストを実行すると、StorybookのPlay function のようにブラウザ上で実際にテストを実行している様子が伺えます(かなり高速に動いています)。
Speed
Browser Modeとjsdomでのテストの実行速度の差ですが、今回デモで使ったコンポーネントで20msほど差がありました。
環境 | 実行速度 |
---|---|
Browser Mode | 95ms |
jsdom | 75ms |
これを大きいと見るか小さいと見るかは人それぞれだと思いますが、個人的には小さいと思っており、Browser Modeによる実行速度の劣化はあまり心配しなくても良いのではないかと思っています。
Finish
Browser Modeを使用することにより、テスト環境の構築(jsdomの設定など)が不要となり、リアルな環境でコンポーネントのテストをすることができるようになりました。個人的にはRadix UIのようなコンポーネントをテストする際に ResizeObserver など色々と不毛なmockを書くことが多かったので、そこら辺が解決され嬉しいです。
Discussion