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
330
フロントエンドの単体テストの使い方/考え方
Tomoya Kashifuku
March 16, 2023
Tweet
Share
More Decks by Tomoya Kashifuku
See All by Tomoya Kashifuku
Rustでオリジナルnpmパッケージを作ってみよう
tnyo43
0
290
ユーザのためだけじゃない!エンジニアも嬉しいアクセシビリティ改善のための自動テスト
tnyo43
0
640
ルールの運用から始めるフロントエンド開発改善
tnyo43
5
2.9k
Elm でつくるルービックキューブ
tnyo43
1
470
Other Decks in Programming
See All in Programming
[初登壇@jAZUG]アプリ開発者が気になるGoogleCloud/Azure+wasm/wasi
asaringo
0
130
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
190
Bytecode Manipulation 으로 생산성 높이기
bigstark
2
360
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
760
Passkeys for Java Developers
ynojima
3
870
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
810
C++20 射影変換
faithandbrave
0
500
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
380
XSLTで作るBrainfuck処理系
makki_d
0
210
Datadog RUM 本番導入までの道
shinter61
1
310
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
11
2.7k
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
370
Featured
See All Featured
Testing 201, or: Great Expectations
jmmastey
42
7.5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Unsuck your backbone
ammeep
671
58k
We Have a Design System, Now What?
morganepeng
52
7.6k
4 Signs Your Business is Dying
shpigford
184
22k
For a Future-Friendly Web
brad_frost
179
9.8k
Producing Creativity
orderedlist
PRO
346
40k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.8k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.8k
Navigating Team Friction
lara
187
15k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
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