Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
フロントエンドの単体テストの使い方/考え方
Search
Tomoya Kashifuku
March 16, 2023
Programming
0
270
フロントエンドの単体テストの使い方/考え方
Tomoya Kashifuku
March 16, 2023
Tweet
Share
More Decks by Tomoya Kashifuku
See All by Tomoya Kashifuku
Rustでオリジナルnpmパッケージを作ってみよう
tnyo43
0
130
ユーザのためだけじゃない!エンジニアも嬉しいアクセシビリティ改善のための自動テスト
tnyo43
0
510
ルールの運用から始めるフロントエンド開発改善
tnyo43
5
2.7k
Elm でつくるルービックキューブ
tnyo43
1
420
Other Decks in Programming
See All in Programming
Effective Signals in Angular 19+: Rules and Helpers @ngbe2024
manfredsteyer
PRO
0
130
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
3
350
[JAWS-UG横浜 #76] イケてるアップデートを宇宙いち早く紹介するよ!
maroon1st
0
460
MCP with Cloudflare Workers
yusukebe
2
220
急成長期の品質とスピードを両立するフロントエンド技術基盤
soarteclab
0
930
Mermaid x AST x 生成AI = コードとドキュメントの完全同期への道
shibuyamizuho
0
160
nekko cloudにおけるProxmox VE利用事例
irumaru
3
430
KubeCon + CloudNativeCon NA 2024 Overviewat Kubernetes Meetup Tokyo #68 / amsy810_k8sjp68
masayaaoyama
0
250
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
330
Итераторы в Go 1.23: зачем они нужны, как использовать, и насколько они быстрые?
lamodatech
0
750
ブラウザ単体でmp4書き出すまで - muddy-web - 2024-12
yue4u
3
470
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
1
650
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Building an army of robots
kneath
302
44k
A designer walks into a library…
pauljervisheath
204
24k
We Have a Design System, Now What?
morganepeng
51
7.3k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
What's in a price? How to price your products and services
michaelherold
243
12k
Producing Creativity
orderedlist
PRO
341
39k
Facilitating Awesome Meetings
lara
50
6.1k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
A Modern Web Designer's Workflow
chriscoyier
693
190k
A better future with KSS
kneath
238
17k
Transcript
フロントエンドの単体テストをやる前に知りたい フロントエンドの単体テストの考え方 カシフクトモヤ 2023/03 1
目的 • フロントエンドで実装する単体テストがカバーする範囲を知る • 単体テストで壊れにくいテストを実装するための思想を知る • 思想に基づいた運用方法を考えられるようにする 2
種本(種記事) • 単体テストの考え方 /使い方(Vladimir Khorikov) • React でつくるフォーム UI の単体テストと
TDD • testing-library でユーザの気持ちになって書くフロントエンドのテスト 3
目次 • フロントエンドの単体テストって何? • フロントエンドの単体テストって、具体的にはどうするの? • フロントエンドのテストをうまく運用するにはどうしたらいいの? 4
目次 • フロントエンドの単体テストって何? • フロントエンドの単体テストって、具体的にはどうするの? • フロントエンドのテストをうまく運用するにはどうしたらいいの? 5
フロントエンドで何をテストしたい? • 意図しない見た目の変更が発生してないか検知したい • ロジックが正しいことを確認したい • ユーザの動作によって起こる挙動を確認したい 6
どういうテストで解決できるの? 意図しない見た目の変更が発生してないか検知したい Visual Regression Test (VRT) を使って解決できるかも。 コンポーネント(もしくは画面)のキャプチャを撮って、変更前と比較する。 変更の有無を見た目だけで判断する。 7
クリック クリック 角の形が変わったことを検知したい
どういうテストで解決できるの? ロジックが正しいことを確認したい 単体テストで検査できるかも 関数としてロジックを定義すると出力値ベーステスト (*1) クラスやカスタムフックとしてロジックを持つと出力値ベーステストと状態ベーステスト 8 *1 単体テストの考え方 /使い方
第6.1章 状態 入力値 出力値 ここを検査したい
どういうテストで解決できるの? ユーザの動作によって起こる挙動を確認したい 単体テスト(統合テスト)や E2E テストで検査できるかも (*1)。 ツールを使ってユーザの動作をシミュレートし、ソフトウェアの動作を確認する。 • 表示の変化は状態ベース・テスト •
API 通信や処理の実行はコミュニケーションベース・テスト 9 *1 ここでは、単体テストと統合テストを明確に区別せず、まとめて単体テストと呼ぶこととします。
テストの種類とできること 「単体テストだけ」や「VRT だけ」など、ある一つのみで全てを解決することはできない。 テストの特性に合わせて適切なテストを実装するとよい。 10 VRT 見た目の 変更の検査 ロジックの 正しさ
書き方の正しさ ユーザの動作に対する 正しい応答 画像引用 “https://testingjavascript.com/” 品質保証 〇 実行速度 ▲ 品質保証 ▲ 実行速度 〇
今回のテーマは単体テスト フロントエンドの実装において、単体テストで検査したいのは大きく次の 2つ。 • ロジックの正しさ • ユーザの動作に対する正しい応答 「ロジックの正しさ」の検査はフロントエンドだけの話ではない。 ここではフロントエンドの単体テストを「 ユーザの動作に対する正しい応答
」の検査であると定義する。 11
目次 • フロントエンドの単体テストって何? • フロントエンドの単体テストって、具体的にはどうするの? • フロントエンドのテストをうまく運用するにはどうしたらいいの? 12
「ユーザの動作に対する正しい応答」って何? たとえば、次のようなユースケースのテストを作りたい。 • ユーザが要素に値を入力してボタンをクリックすると、 API リクエストが送られる • チェックボックスを全て選択していないと、ボタンがクリックできない状態になっている • キーボードで
[Ctrl + F] と入力すると、検索窓にフォーカスされる 13
「ユーザの動作」と「正しい応答」を分析する • ユーザの動作 ◦ 操作したい要素を見つける ◦ マウスのクリック ◦ キー入力をする •
正しい応答 ◦ 要素を変化させる ▪ 特定の文字列が表示される /非表示になる ▪ 入力要素がフォーカスされている ◦ API にリクエストを送る / callback 関数を実行する 14
ユーザの動作の再現に使える testing-library testing-library はフロントエンドのテストに用いるツールとして知られている。 React、Vue、Svelte などで動作するライブラリ。 要素を見つける、マウスのクリックやキー入力をするといったユーザの動作をシミュレートできる。
「テストをソフトウェアの使用方法に似せる」という基本方針 にしたがって使うことが推奨されている。 15
要素を見つけるクエリ testing-library は要素を見つけるためのクエリ を提供している。 クエリには優先順位がついていて、優先順位が高いほど「ソフトウェアの使用方法に似た」テストを作れる傾向に ある (*1)。 • getByRole
• getByLabelText • getByPlaceholderText • getByText • getByAltText • getByTitle • getByTestId 16 *1 実装の方針によっては優先順位が低いクエリを使ったほうがいいケースもある。 優先度が高い 低い
要素を見つけるクエリの優先度を考える 17 優先順位を考えるとき、ユーザがどのように要素を見つけるかを考えるのがポイント。 例)『生年月日』の入力要素を見つけるクエリ • getByRole は WAI-ARIA ロールを使って要素を探すクエリ •
getByPlaceholderText はプレースホルダーを使って要素を探すクエリ getByRole を使ったほうがユーザがどのように要素を見つけるかを反映している。
ユーザのアクションを再現する testing-library はユーザの動作を再現するためのライブラリ user-event を提供している。 クリックやキーボードのタイプを、かなり直感的に再現できるようになっている。
18
要素の変化を検知する testing-library/jest-dom というライブラリで、要素の検査ができるようになる。 直感的に状態を確認できる関数を提供している。 実装時に「ユーザが要素の状態を認識する根拠となる状態のあり方」を知らなくてよい。 • toBeInTheDocument (表示されていることを確認) • toHaveFocus
(フォーカスされていることを確認) • toHaveValue (値が入力されていることを確認) • etc… 19
API にリクエストを送る / callback 関数を実行する API のリクエストは MSW などのライブラリを活用してモックサーバを使って検査できる。 callback
関数の検査は jest のモック関数を使って検査できる。 (詳細は省略) 20
テストを実装してみよう 次のようなコンポーネントのテストを実装する。 • 3つの入力要素があって、下の画像のような出力になる 次のようなテストを作る • 適切なデータを入力して『送信』ボタンを クリックすると、props で渡す”submit” が呼ばれる
• 必須項目の『名前』を空欄にして送信すると、 “submit” が呼ばれず警告のメッセージが表示される 21 テスト対象の UI
テストを実装してみよう 適切なデータを入力して 『送信』ボタンをクリックすると、 props で渡す ”submit” が呼ばれる 22
テストを実装してみよう 必須項目の『名前』を 空欄にして(『名前』以外を入力する) 送信すると、 “submit” が呼ばれず 警告のメッセージが表示される 23
本当にテストを実装できるの? 24 一般に、ソフトウェアのテストのしやすさの度合いを「テスト容易性」として表す。さらに分割すると、次のような要 素に分けられる(*1)。 • テスト容易性は実行円滑性(テスト実行での支障の少なさ) • 観測容易性(テスト対象の出力の取得しやすさ) • 理解容易性(テスト対象の理解のしやすさ)
• etc… フロントエンドのテストの難しい場合、多くは(特に状態の)観測容易性が低いからではないかと思う。 *1 https://www.qbook.jp/column/20190410_753.html より引用
観測可能性が高いコードって何? 25 適切な style を与えると、どちらでも同じように実装できる。
観測可能性が高いコードって何? 26 テスト容易性が低い状態であるが、それと同時に マシンリーダビリティが低い状態 でもある。 ラベルと要素が紐づかないので入力要素を観測できない ボタンとして認識されないので観測できない
テスト容易性とマシンリーダビリティ 27 マシンリーダビリティとは機械にとってのコンテンツを読み取りやすさの度合いのこと (*1)。 ブラウザや支援技術などのユーザエージェントがコンテンツを解釈できるようにするためには マシンリーダビリティの向上が欠かせない。 フロントエンドのテストは、 機械がコンテンツを読み取ったり操作をしたり してソフトウェアの動作をシミュレーショ ンする。
マシンリーダビリティが高いほうがテスト容易性が高くなる 傾向にある。 フロントエンドのテストの導入の前に、マシンリーダビリティ(ひいてはアクセシビリティ)の向上を目指すとよい。 *1 Webアプリケーションアクセシビリティ p43-45 より引用
目次 • フロントエンドの単体テストって何? • フロントエンドの単体テストって、具体的にはどうするの? • フロントエンドのテストをうまく運用するにはどうしたらいいの? 28
テストを作る目的を明確にする (単体テストだけでなく)目的が明確でないテストは負債になる。 • テストの目的は何か • 目的を果たすためにはどのように実装すべきか • 誰から見ても理解しやすいか 対象となるソフトウェアやチームの思想によって いいテストのあり方も変わる。
「動くが自明で意味を持たないテスト」「壊れやすいテスト」「自己満足なテスト」は 負債になって、むしろ開発の妨げになる。 29
アクセシビリティのガイドラインを定める アクセシビリティはユーザ体験に影響を与える 外部品質のため。 テスト容易性は開発者体験にのみ影響を与える 内部品質のため。 内部品質を優先させるために外部品質を(著しく)棄損してはいけない。 まずはアクセシビリティのガイドラインを作ってから、それに沿ったテストを考えるのがセンスがよさそ う。 アクセシビリティのガイドラインで規定されていない部分はテストのしやすさを基準に決めてもよい。 30
まとめ フロントエンドのテストは単体テストだけではなく VRT や E2E テストもある。 フロントエンドの単体テストで確認したいのは ユーザの動作に対する正しい応答 。 ユーザの動作に対する正しい応答を検査するようなテストでは、
testing-library をうまく使う必要があ る。使う前にツールの思想を理解するとよい。 テストをうまく運用するためには、テストの目的を明確にすることが大切。 フロントエンドのテストよりも前に アクセシビリティのガイドラインがあると方針を立てやすい 31