Slide 1

Slide 1 text

2024/09/20 Encraft #18 コンポーネントテストの手法と その効果を考える

Slide 2

Slide 2 text

nus3(なすさん)

Slide 3

Slide 3 text

今日話したいこと はじめに 各ライブラリの特徴 各ライブラリのベンチマーク 各ライブラリの違い コンポーネントテストの効果を考える

Slide 4

Slide 4 text

今日話したいこと はじめに 各ライブラリの特徴 各ライブラリのベンチマーク 各ライブラリの違い コンポーネントテストの効果を考える

Slide 5

Slide 5 text

お詫び 発表時間に対して スライドを作りすぎてしまいました 割愛した部分は公開したスライドを ご覧ください

Slide 6

Slide 6 text

コンポーネントテストとは

Slide 7

Slide 7 text

コンポーネントテストとは フロントエンドのコンポーネントを対象にしたテスト

Slide 8

Slide 8 text

コンポーネントテストとは フロントエンドのコンポーネントを対象にしたテスト ❶対象のコンポーネントをレンダリング コンポーネントテストとは

Slide 9

Slide 9 text

コンポーネントテストとは フロントエンドのコンポーネントを対象にしたテスト ❷レンダリングしたコンポーネントを操作 コンポーネントテストとは

Slide 10

Slide 10 text

コンポーネントテストとは フロントエンドのコンポーネントを対象にしたテスト ❸意図した挙動になっているか確認 コンポーネントテストとは

Slide 11

Slide 11 text

コンポーネントテストとして 使えるツール、ライブラリ が増えてきた

Slide 12

Slide 12 text

例えば Safetest Playwright Testing Library Jest Vitest (Browser Mode) 右にいくほど最近出てきたものな印象

Slide 13

Slide 13 text

それぞれの違いを整理し、 どのような効果があるかを 考えたい

Slide 14

Slide 14 text

今日話したいこと はじめに ! 各ライブラリの特徴 各ライブラリのベンチマーク 各ライブラリの違い コンポーネントテストの効果を考える

Slide 15

Slide 15 text

それぞれのライブラリで コンポーネントテストを実装 使ったことないツールもあったしね

Slide 16

Slide 16 text

使用したライブラリ 5 Vites" 5 jsdom、Plawright(Browser Mode)、 WebdriverIO(Browser Mode 5 Playwright 5 Storybook (@storybook/test-runner 5 WebdriverII 5 Cypres8 5 Safetest

Slide 17

Slide 17 text

ライブラリの特徴を それぞれ、ざっくり紹介 スライド作りすぎちゃっタ

Slide 18

Slide 18 text

Vitest € Vite-nativeなテストフレームワーy € Viteと同じ設定でテストを実行できI € Jestとの互換性を意識したインターフェーQ € Testing Libraryを使えI € Browser Mode(experimental)ができたことで、
 コンポーネントをブラウザ上にレンダリングし、
 テストを実行できる

Slide 19

Slide 19 text

Playwright WebdriverIO 設定を切り替えるだけで 同じテストを別の動作環境で実行できる Vitest

Slide 20

Slide 20 text

Vitest Testing Libraryを組み合わせたJestのような記法が使える

Slide 21

Slide 21 text

Playwright w Mircosoftq w @storybook/test-runnerやVitestのprovider、SafeTestで 使われていp w experimentalだが、コンポーネントをブラウザ上に
 レンダリングし、テストを実行することも可 w コンポーネントのbundleとserveにはViteを使っている https://playwright.dev/docs/test-components#under-the-hood

Slide 22

Slide 22 text

Playwright https://playwright.dev/docs/test-components#step-2-create-a-test-file-srcappspectstsx React、Svelte、Vue、SolidJSに対応

Slide 23

Slide 23 text

Playwright https://playwright.dev/docs/testing-library#cheat-sheet 記法は違えど、 Testing Libraryのような 書き方もできる

Slide 24

Slide 24 text

R コンポーネントの開発環境E R R コンポーネントの開発フロー(Chromatic$ R コンポーネントのテス6 R Chromatic 、@storybook/test-runnerを使い、
 play関数に書いた内容をブラウザ上でテストできる コンポーネントのドキュメントE Interaction Testみたいな呼び方もあった気がしたけど、 新しいドキュメントではComponent testで統一されていたでござる

Slide 25

Slide 25 text

play関数を使った コンポーネントのテスト

Slide 26

Slide 26 text

PlaywrightのコンポーネントテストにStoryを使う
 (Portable stories) https://storybook.js.org/docs/api/portable-stories/portable-stories-playwright

Slide 27

Slide 27 text

PlaywrightのコンポーネントテストにStoryを使う
 (Portable stories) https://storybook.js.org/docs/api/portable-stories/portable-stories-playwright Portable storiesは名前からも Storybookで定義したStoryを色んなテストフレームワークで 使えるようにしたいって思いがありそう ※個人の感想です

Slide 28

Slide 28 text

WebdriverIO R Node.jsで実行できるブラウザ、モバイルのテスト自動化 フレームワーT R クロスブラウザに対4 R コンポーネントをブラウザ上にレンダリングし、
 テストを実行できD R Lit、Vue、Svelte、SolidJS、React、Preact、Stencil
 に対応 Stencil初耳だったわ

Slide 29

Slide 29 text

WebdriverIO Testing Libraryが使えるのでVitestと同じような記法で書ける

Slide 30

Slide 30 text

R コンポーネントをブラウザ上にレンダリングし、
 テストを実行できX R 公式ではReact、Angular、Vue、Svelteに対1 R R Cypress Cloudというエンタープライズ向けのSaaSがあX R テストの解析やテストの並列化など、テストに関する 機能を提供 別ライブラリに対応するためのAPIも公開してそƒ

Slide 31

Slide 31 text

spyなど独特な記法はあれど、他ライブラリと似たような
 記法で書ける

Slide 32

Slide 32 text

Safetest t Netfilxで採用されているテストフレームワーr t コンポーネントをブラウザ上にレンダリングし、
 テストを実行できH t ブラウザ上の操作にはPlaywrightを使ってH t JestやVitestのテストランナーを使えH t セットアップが簡! t ReactなどのUIライブラリに依存しない

Slide 33

Slide 33 text

Safetest ここから先は Safetestを実際に使ってみて、 READMEを読んだ 程度の知識で喋ります 間違ってたら懇親会の時に優しく教えてね

Slide 34

Slide 34 text

Safetest Safetestのセットアップファイルを作成 アプリのエントリーポイントを指定する

Slide 35

Slide 35 text

Safetest アプリのエントリーポイントでSafetestのbootstrapを呼ぶ

Slide 36

Slide 36 text

Safetest アプリのエントリーポイントでSafetestのbootstrapを実行する このbootstrapが実行される際にglobで指定した
 .safetest.tsxファイルを別々にバンドル

Slide 37

Slide 37 text

Safetest コンポーネントのテストを書く

Slide 38

Slide 38 text

Safetest `s あらかじめアプリケーションを起動しておく
 (npm run devなどW Ts Node.js: テストの中でrender関数が呼ばれるとブラウザ上でアプリケーション の画面に遷移しようとすE as ブラウザ: bootstarpが呼ばれると、importGlobで指定され、バンドルされた モジュール(コンポーネント)とテストケースがマッピン™ s ブラウザ: render関数で指定されたコンポーネント(モジュール)を
 importし、ブラウザ上にレンダリン™ 8s Node.js側に戻り、render関数以降のテストがPlaywright実行 多分、こんな流れのはず

Slide 39

Slide 39 text

今日話したいこと はじめに 各ライブラリの特徴 4 各ライブラリのベンチマーク 各ライブラリの違い コンポーネントテストの効果を考える

Slide 40

Slide 40 text

それぞれのライブラリで テストを実行した際にかかった時間を計測

Slide 41

Slide 41 text

用意したコンポーネント

Slide 42

Slide 42 text

È3 各inputに値を入# 3 Submitボタンをクリッ Ç3 onSubmitが実行されÄ Â3 入力された値が引数に渡される 用意した⁨⁩テストケース

Slide 43

Slide 43 text

50ケースあるテストファイルを5つ用意 × 5ファイル テストの実行量はなんとなくです。特に意味はないヨ

Slide 44

Slide 44 text

計測したライブラリ 8 Vitest + jsdoE 8 Vitest (Browser Mode) + Playwrigh( 8 Vitest (Browser Mode) + WebdriverIA 8 WebdriverIA 8 Storybook (@storybook/test-runner! 8 Safetest 今回実装した内容は以下のリポジトリにあるヨ (⁨⁩色々整ってないけど、許してネ) https://github.com/nus3/benchmark-component-test

Slide 45

Slide 45 text

計測しなかったライブラリ q Cypressのコンポーネントテストはデフォルトだと、ファイルごとで
 並列にテストが実行されず、あまりにも実行時間が長くなったので除W q 並列で実行するにはCypress Cloudを使う必要があH q Playwrightのコンポーネントテストは用意したテストケースを満たすような
 テストがかけず時間切U q コンポーネントテストでonSubmitをモックして、submit時に引数の値を
 確認する方法がオラにはわからなんだ Playwrightのコンポーネントテスト、ガンガン使ってますって人がいたら、ぜひ話そ

Slide 46

Slide 46 text

計測に使ったスクリプト https://github.com/nus3/benchmark-component-test/blob/main/scripts/benchmark.ts 各ライブラリ、どんくらい時間かかったんやろなぁ〜ぐらいの 軽い気持ちで見てもらえると

Slide 47

Slide 47 text

計測結果 ※ちゃんと有意差を示すにはサンプリングの回数がもっと
 必要だと思うので、あくまで参考程度に

Slide 48

Slide 48 text

計測結果 ※ちゃんと有意差を示すにはサンプリングの回数がもっと必要だと思うので、あくまで参考程度に ※計測した後に気づいたが一部の条件が平等ではない { StorybookとSafetestはテストの実行以外に、
 Storybookのビルドやアプリのサーバー起動が必要で、
 その時間を含められてなy { vitest-wdioはVitest側からproviderOptionsを使って並列に実行する設定を
 渡せていない ほんとに単純な実装しかしてないので、考慮漏れとかあれば教えてください

Slide 49

Slide 49 text

今日話したいこと はじめに 各ライブラリの特徴 各ライブラリのベンチマーク C 各ライブラリの違い コンポーネントテストの効果を考える

Slide 50

Slide 50 text

ライブラリそれぞれで 何が違うのか

Slide 51

Slide 51 text

コンポーネントがレンダリングされる
 場所の違い b コンポーネントはNode.js上でレンダリングされ2 b コンポーネントの操作時に使われるDOM API等は
 jsdomがエミュレートしてくれる + Jest Vitest

Slide 52

Slide 52 text

コンポーネントがレンダリングされる
 場所の違い A コンポーネントはブラウザ上でレンダリングされ% A コンポーネントの操作は実際のブラウザ上で行われる Safetest Playwright WebdriverIO

Slide 53

Slide 53 text

自動ブラウザテストの違い Playwright WebdriverIO ブラウザの自動操作をする際の アーキテクチャがそれぞれ違う

Slide 54

Slide 54 text

自動ブラウザテストの違い Playwright WebdriverIO ブラウザの自動操作をする際の アーキテクチャがそれぞれ違う アーキテクチャの違いについてはtogamiさんのZennの記事が とてもわかりやすくて、ありがたかったでござる https://zenn.dev/togami2864/articles/65af759b4a34f6

Slide 55

Slide 55 text

WebDriver WebdriverIO https://www.neovasolutions.com/2022/05/19/browser-automation-tools-protocols-webdriver-vs-cdp/ – 標準化されたWebDriverというプロトコルを使ってブラウザを操R – 各ブラウザではWebDriverプロトコルに対応したDriverを持っていH – クロスブラウザに対d – 間にDriverが必要で、一方向通信

Slide 56

Slide 56 text

Chrome DevTools Protocol(CDP) https://brahmakothapalli.hashnode.dev/playwright-01-selenium-playwright-architecture-comparison t CDPを使ってブラウザを操™ t Chromiumベースのブラウザでしか使えなƒ t PlaywrightではFirefox、Safariでも操作できるようにパッチを当てていV t Driverが間に必要ない、またWebSocketを使った双方向通信を行なっている Playwright WebdriverIO

Slide 57

Slide 57 text

Native https://github.com/cypress-io/cypress-documentation/issues/872#issuecomment-586708267 • ブラウザ上にCypressのテストランナーがあe • 対象のコンポーネントを直接操P • windowやdocumentなどブラウザ上のオブジェクトにもアクセスできe • 複数タブや複数ブラウザを同時に制御できない

Slide 58

Slide 58 text

WebDriver BiDi c 新しいプロトコルで仕様の策定が進められていF c WebDriverの遅さ、CDPのChromium依存という
 両ライブラリの問題点を解消したプロトコX c c c Chrome、Edge、Firefoxでの実装が進んでF Puppeteer v23でFirefoxを操作する際に
 WebDriver BiDiがデフォルト€ WebDriverIOでもv9からWebDriver BiDiがデフォルトに

Slide 59

Slide 59 text

今日話したいこと はじめに 各ライブラリの特徴 各ライブラリのベンチマーク 各ライブラリの違い Y コンポーネントテストの効果を考える

Slide 60

Slide 60 text

それぞれの違いから コンポーネントテストの 効果を考える ラストスパートだ!ここからは個人の意見だヨ!!

Slide 61

Slide 61 text

jsdomを使ったコンポーネントテスト ‡ Node.jsで完結する分、導入コストは低く、
 実行時間も短X ‡ 操作手順が少ない(シンプルな)コンポーネントを対象と したテストに最™ ‡ 複雑な手順のコンポーネントを対象にしたテストは
 デバッグがしづらX ‡ ブラウザ上とは異なる挙動になる場合もあd ‡ クリック可能か、z-index、フォーカス、Canvas

Slide 62

Slide 62 text

そもそもシンプルなコンポーネント に対するテストは必要なのか e 品質の担保というより、設計を見直す機会として捉えてW e シンプルなコンポーネントのはずなのに...
 テストが書きづらいぞ...何だ...何かがおかしい..` e copilotやエディタの拡張の登場もあり、コンポーネントテストを書くコストは
 低くなってW e シンプルなコンポーネントな分、テストコード自体も読みやすい→変更箇所の 対応がしやすい→不要な場合に消しやすい

Slide 63

Slide 63 text

ブラウザを使ったコンポーネントテスト n ブラウザ上でレンダリングされるという信頼性の高“ n 挙動が違うんじゃないかという心配がいらなo n E2Eと比べると導入コストは低く、実行時間も短o n 複雑なコンポーネントのデバッグをブラウザ上で
 確認できR n experimentalなライブラリが多いが、これらがstableにな ることで、コンポーネントに対して品質を担保したい時の
 第1の選択肢になりうるのでは

Slide 64

Slide 64 text

ブラウザを使ったコンポーネントテスト s クロスブラウザ対応はWebDriver BiDiの動向が気になˆ s 仕様の策定がどう進んでいくg s 各ブラウザ、テストツールはどう対応するのg s 現状、experimentalなものが多t s ドキュメントや導入事例が十分ではないことT s E2Eほどではないが、実行時間はjsdomと比べて長そ7 s 全てのコンポーネントをブラウザ上で
 レンダリングし、テストする必要はない

Slide 65

Slide 65 text

コンポーネント開発環境として • コンポーネントの開発からテストまでStorybook上で行q • Storybookには、開発環境、ドキュメント、テスト、VRT などコンポーネント開発に関わる機能が揃っていI • play関数を使ったコンポーネントテストのデバッグが優) • ブラウザ上でテストを1ステップずつ確認できI • Storybookの環境は自前で構築してもいいし、
 お金をかけてChromaticに任せちゃってもいい

Slide 66

Slide 66 text

キニナル点

Slide 67

Slide 67 text

Next.jsとコンポーネントテスト ‚ Next.js(App Router)とコンポーネントテストの関係が
 どうなっていくのかワタシキニナリマQ ‚ Client ComponentをテストするのはイメージできI ‚ Suspense使ってる(SSR Streaming)コンポーネントを 対象にブラウザを使ったコンポーネントテストは
 できるの8 ‚ コンポーネントテスト側でも同じ挙動が
 再現できるのか

Slide 68

Slide 68 text

ぜひ、皆さんの考えも 聞かせてください〜 本日は聞いてもろてありがとネ〜