この記事は FastDOCTOR After Advent Calendar 30日の記事です。
TL;DR
Jestといったjsdom実装のコンポーネント単体テストフレームワークの代替ソリューションとして、Cypressのコンポーネントテスト機能を試しました。
自己紹介
Webエンジニアの藤井です。
FDでは法人事業におけるWebサービスの開発を担当しております。
背景
弊事業において新たなプロジェクトの発足に伴い、新規プロダクトのテスト環境を模索しておりました。
私はこれまで、Jestに内包されているjsdomを使ってコンポーネントの単体テストを行ってきました。
しかしjsdomはあくまでエミュレーターという性質上、ブラウザ上で実行するjsと同じ動作を保証するものではありません。またコンポーネントの描画を目視で確認できない点に不満を感じていました。
そこで、jsdom以外の別のコンポーネントの単体テスト方法を模索する中で、Cypressのコンポーネントテスト機能に出会いました。
Cypressのコンポーネントテスト機能は、jsdomの欠点を補うような機能が備わっており、非常に使い勝手が良いと感じました。
Cypressのコンポーネントテスト機能は、jsdomと比べて以下のメリットがあります。
- ブラウザ上でテストが実行されるためテストの信頼性が高い
- テストの目視確認が可能
- シナリオのセットアップが容易
- Cypressはall-in-oneをコンセプトに掲げており、テストの実装までの手数が少ない
- assertionや外部通信へのモックといった必要なものは大体ビルトインされている
- Cypressはall-in-oneをコンセプトに掲げており、テストの実装までの手数が少ない
そこで、今回はCypressのコンポーネントテスト機能を使って、簡単なコンポーネントの単体テストを動かしてみようと思います。
準備
CypressによるNext.jsのE2EテストのサンプルをVercelが既に用意しているので、そちらを利用しようと思います。が該当環境は情報が古いため、最低限動かすための変更を加えたリポジトリを私の方で別途用意しました1。
$ git clone git@github.com:KentFujii/with-cypress-app.git
$ npm install
$ npm run component
上記を実行後、下記のような画面が表示されれば準備は完了です
テストの実行
するとテストが実行されます。またテストの対象のコンポーネントが、テストスイートと共に描画されていることがわかります。
実行されたテストの内容は下記です
import AboutComponent from 'components/about-component'
describe('<AboutComponent />', () => {
it('should render and display expected content in a Client Component', () => {
cy.mount(<AboutComponent />)
cy.get('h1').contains('About Page')
cy.get('a[href="/"]').should('be.visible')
})
})
仕組み
Cypressのコンポーネントテスト機能は、下記の通りに動作するようです。
コンポーネントはページから分離されたブラウザにレンダリングされ、そのスタイルやAPIが検証されます。
- コンポーネントをビルドして、ブラウザにマウントしレンダリングする
- ビルド設定はこちらにあります
- マウントはこちらのHTMLに対しこちらから実行されているようです
- 各コンポーネントを各テストからcy.mount()でマウントし、レンダリングが実行されます
- コンポーネントの要素を特定して、操作や検証を行う
- 検証結果が期待通りであるかどうかを判断する
-
should()
検証を行う - 詳しくはドキュメントのAssertionsを参照
-
まとめ
Cypressのコンポーネントテスト機能は、jsdomの欠点を補うような機能が備わっており、非常に使い勝手が良いと感じました。テストを用意し動かすまでの手数が少ないのも魅力的です。
繰り返しになりますが、以下の点がメリットとして挙げられます。
- ブラウザ上でテストが実行されるためテストの信頼性が高い
- テストの目視確認が可能
- シナリオのセットアップが容易
- Cypressはall-in-oneをコンセプトに掲げており、テストの実装までの手数が少ない
もしjsdom以外のコンポーネントテスト方法を模索しているのであれば、Cypressのコンポーネントテスト機能は検討してみる価値があると思います。
後日譚
実は前述の新規プロジェクトにおいてCypressの採用は見送りました。弊社の開発環境は可能な限りDockerに寄せるという方針ですが、Cypressの仕組み自体がDockerと相性が悪いようです。別案として@storybook/test-runnerを検討していますが、何か他に良いソリューションがあれば教えてください。
-
該当リポジトリは2023/12/25時点で動作を検証したものであり、今後も含めた動作を保証するものではありません ↩