Slide 1

Slide 1 text

テストピラミッドを意識したテスト コード実装戦略 PHP Conference Japan 2020 Track4-3-B #track4-3-b-test-pyramid 02

Slide 2

Slide 2 text

Who’s 02? 名前: 02 (大津和槻) Twitter: @cocoeyes02 職業: Webエンジニア(主にバックエンド) 経歴: PHPカンファレンス2019 登壇 「PHPerのためのテストコード入門」

Slide 3

Slide 3 text

今回の登壇で話すこと ● テストピラミッドについて解説 ● テストピラミッドを意識しながら、実際にLaravelとPHPをバージョンアップした事例 共有

Slide 4

Slide 4 text

今回の登壇で話さない(話せない)こと ● どのプロダクトにも適応できるテストコード実装戦略

Slide 5

Slide 5 text

今回のゴール テストコード実装戦略実例を通して、 テストピラミッドについて 理解が深められること

Slide 6

Slide 6 text

アジェンダ ● テストピラミッドとは? ● 各層のテストの紹介 ● 実例:Laravelチュートリアルのバージョンアップ

Slide 7

Slide 7 text

テストピラミッドとは?

Slide 8

Slide 8 text

ユニットテスト 統合テスト テストピラミッドと は? Mike Cohn氏が ”Succeeding with Agile”で 最初に提唱した 3つのテストのコストと実装 すべきテスト量を 示したも の UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 9

Slide 9 text

ユニットテスト 統合テスト テストピラミッドと は? コスト ● 実行時間 ● テスト範囲 ● 修正工数 ○ メンテナンス ○ テスト失敗時の原 因特定 UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 10

Slide 10 text

ユニットテスト 統合テスト テストピラミッドと は? 実装すべきテスト量 ● テストのケース量 ○ 正常系・異常系 ○ パターン テスト結果(成功/失敗)が わかるまでかかる時間 ≒実行時間×テストケース量 UI テスト 実 装 す べ き テ ス ト 量 小 多 コ ス ト 大 小

Slide 11

Slide 11 text

フィードバックループ フィードバックを得るまでにかかる時間 を図示したもの 「テスト結果(成功/失敗)がわかるまで かかる時間」がそのまま「フィードバック を得るまでにかかる時間」になる wikipedia "Extreme programming"https://en.wikipedia.org/wiki/Extreme_programming

Slide 12

Slide 12 text

フィードバックループ フィードバックを得るまでにかかる時間 を図示したもの 「テスト結果(成功/失敗)がわかるまで かかる時間」がそのまま「フィードバック を得るまでにかかる時間」になる →コストが少ないテストの方が、 生産 性↑に繋がりやすい wikipedia "Extreme programming"https://en.wikipedia.org/wiki/Extreme_programming

Slide 13

Slide 13 text

各層のテストの紹介

Slide 14

Slide 14 text

ユニットテスト 統合テスト 各層のテストの紹介 ● UIテスト ● 統合テスト ● ユニットテスト UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 15

Slide 15 text

ユニットテスト 統合テスト UIテスト 最もユーザ目線に近い。 Webサービスではブラウザ を自動操作し、   期待通 りの動作をしているか検証 する Seleniumなどを利用した E2Eテストがこれに当たる。 UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 16

Slide 16 text

ユニットテスト 統合テスト 統合テスト 特定のインプットを渡し 返ってきた内容が   正し いかどうかを検証 Featureテスト(Laravelの httpテスト)や、WebAPIを 使ったテストはこれに当た る UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 17

Slide 17 text

ユニットテスト 統合テスト 統合テスト 特定のインプットを渡し 返ってきた内容が   正し いかどうかを検証 Featureテスト(Laravelの httpテスト)や、WebAPIを 使ったテストはこれに当た る UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多 値、リクエス トなど

Slide 18

Slide 18 text

ユニットテスト 統合テスト ユニットテスト 一つの関数やメソッドに対 して、I/Oを通して  仕様通 りの挙動をしているか検証 する PHPでは、PHPUnitを使う 例が多い UI テスト コ ス ト 大 小 実 装 す べ き テ ス ト 量 小 多

Slide 19

Slide 19 text

実例題材 LaravelチュートリアルのバージョンUP

Slide 20

Slide 20 text

Laravel Tutorial

Slide 21

Slide 21 text

Laravel Tutorial ● 超シンプルなTODOリストサービス ○ 新規登録 ○ ログイン ○ ログアウト ○ パスワードリセット ○ タスク追加 ○ タスク削除 ● Laravel 5.2 / PHP5.6 ● 典型的なMVC

Slide 22

Slide 22 text

ユニットテスト 統合テスト Laravel Tutorial 実装されているテストコードは featureテスト(統合テスト)のみ ● TOP画面が開ける ● 新規登録できる ● タスク作成/削除ができる ● 他人のタスクは見れない ● 他人のタスクの削除はできない UI テスト

Slide 23

Slide 23 text

ユニットテスト 統合テスト Laravel Tutorial PHPUnitを使っている(v4.8.36!) ● 実行時間は2秒ほど UI テスト

Slide 24

Slide 24 text

Laravel Tutorial ● 「本番でバグが出ていることに気づかなかった」という状況を回避しつつ、「Laravel Tutorial」をバージョンアップしたい ● バージョンアップ時にエラーが発生する場合は、いち早く気づけるようにしたい

Slide 25

Slide 25 text

テストピラミッドに合わせた方針候補 ● 保険としてUIテストを追加する ● 一部設計を修正してから、ユニットテストを追加する

Slide 26

Slide 26 text

保険としてのUIテストを追加する ● ユーザー目線からのテスト(UIを含めてのテスト)も書いて、さらに担保している感を 強めたい ○ FWのバージョンアップは、どこにバグが現れるかわからない ○ テストコードというのは、自分が書いたコードに自信を持つことも目的の 1つ ● 「全てUIテストで書く」ことはしない ○ 一番ユーザー目線に近いテストなので安心度があるが、全部 UIで書くとテスト時間が長くなる ■ 数十分、数時間かかるテストは運用するの辛い ■ 統合テストよりは少なくする ユニットテスト 統合テスト UI テスト

Slide 27

Slide 27 text

保険としてのUIテストを追加する ● 今回はseleniumを採用 ○ Laravel DuskはLarvael5.4からなので、今回は使えない ○ ChromeやFirefoxなどクロスブラウザでのテストができる余地を残しておく ● 新規登録→ログアウト→ログイン→タスク登録のUIテストを作成した ○ 実行時間は30秒 ユニットテスト 統合テスト UI テスト

Slide 28

Slide 28 text

一部設計を修正してからユニットテストを追加する ● 統合テストでカバーできていないテストは、ユニットテストで担保したい ○ バリデーション ○ モデル ● 一部リファクタリングをして、DBの処理などをモック化できるようにする ユニットテスト 統合テスト UI テスト

Slide 29

Slide 29 text

一部設計を修正してからユニットテストを追加する ● 自分のタスクを一覧表示する機能をリファクタリング ○ 一覧表示するときの条件をクエリで決めるのではなく、 Collectionのメソッドを使って決めるようにし た ○ ユニットテスト時には、「 Collectionのメソッドを使って決めた」部分だけテストすれば良い ユニットテスト 統合テスト UI テスト

Slide 30

Slide 30 text

一部設計を修正してからユニットテストを追加する ● 新規登録時のバリデーションパターンを網羅 ● タスク作成時のバリデーションパターンを網羅 ● 自分のタスクを一覧表示する機能のロジックをテスト ● 実行時間は全部合わせて3.5秒ぐらい ユニットテスト 統合テスト UI テスト

Slide 31

Slide 31 text

Laravel Tutorial バージョンアップの結果は…? ● Laravel 5.2->5.3 ○ 全層のテストコードでエラーを発見した ● Laravel 5.3->5.4 ○ UIテストのテストコードだけエラーを発見した( viewのキャッシュをクリアするコマンド実行が必要 だった) ○ あとはテストコードの修正をした ● Laravel 5.4->5.5, PHP5.6->7.0 ○ 全層のテストコードでエラーを発見した ● Laravel 5.5->5.6, PHP7.0 -> PHP7.1 ○ 全層のテストコードでエラーを発見した

Slide 32

Slide 32 text

Laravel Tutorial バージョンアップの結果は…? ● Laravel 5.2->5.3 ○ 全層のテストコードでエラーを発見した ● Laravel 5.3->5.4 ○ UIテストのテストコードだけエラーを発見した( viewのキャッシュをクリアするコマンド実行が必要 だった) ○ あとはテストコードの修正をした ● Laravel 5.4->5.5, PHP5.6->7.0 ○ 全層のテストコードでエラーを発見した ● Laravel 5.5->5.6, PHP7.0 -> PHP7.1 ○ 全層のテストコードでエラーを発見した

Slide 33

Slide 33 text

Laravel Tutorial バージョンアップの結果は…? ● Laravel 5.2->5.3 ○ 全層のテストコードでエラーを発見した ● Laravel 5.3->5.4 ○ UIテストのテストコードだけエラーを発見した( viewのキャッシュをクリアするコマンド実行が必要 だった) ○ あとはテストコードの修正をした ● Laravel 5.4->5.5, PHP5.6->7.0 ○ 全層のテストコードでエラーを発見した ● Laravel 5.5->5.6, PHP7.0 -> PHP7.1 ○ 全層のテストコードでエラーを発見した

Slide 34

Slide 34 text

Laravel Tutorial バージョンアップの結果は…? ● Laravel 5.2->5.3 ○ 全層のテストコードでエラーを発見した ● Laravel 5.3->5.4 ○ UIテストのテストコードだけエラーを発見した( viewのキャッシュをクリアするコマンド実行が必要 だった) ○ あとはテストコードの修正をした ● Laravel 5.4->5.5, PHP5.6->7.0 ○ 全層のテストコードでエラーを発見した ● Laravel 5.5->5.6, PHP7.0 -> PHP7.1 ○ 全層のテストコードでエラーを発見した →いちいち画面を見ることなく、バージョンアップの作業にもくもくできた

Slide 35

Slide 35 text

最後に ● どのテストも銀の弾丸というわけではない ○ それぞれ長所短所がある ● テストどの層でどの範囲を担保するのか、すり合わせることが大事 ○ 全体を俯瞰して、どの機能がどのテストで担保できているのか見る必要がある

Slide 36

Slide 36 text

参考文献など ● 今回検証に使った環境 ○ https://github.com/cocoeyes02/laravel_test_pyramid ● 参考文献 ○ 初めての自動テスト ――Webシステムのための自動テスト基礎 ○ https://www.oreilly.co.jp/books/9784873118161/