Slide 1

Slide 1 text

xUnit Test Patterns から学ぶ ユニットテスト アンチパターン Connehito Marché vol.5 〜PHP市〜 Kazuki Higashiguchi (@hgsgtk) 1

Slide 2

Slide 2 text

TL;DR About this talk ● ユニットテストを書くのは大事 ● より良いテストを書くのは大事 ● より良いテストをかくための考 え方って何? ● 良くないテストの傾向を知る 2

Slide 3

Slide 3 text

@hgsgtk Kazuki Higashiguchi job is … Software Engineer lang is ... PHP, Go ...etc belongs to ... BASE BANK株式会 社 (BASE株式会社の100%子会社) 3

Slide 4

Slide 4 text

= 4 BASE BANK Mission 「銀行をかんたんにし、全ての人が挑戦できる世の中に」 即座に資金調達ができる金融サービス「YELL BANK(エールバンク)」 https://thebase.in/yellbank

Slide 5

Slide 5 text

『xUnit Test Patterns』 Title: xUnit Test Patterns: Refactoring Test Code Author: Gerard Meszaros 5 https://www.amazon.co.jp/dp/0131495054/ref=cm_sw_r_tw_dp_U_x_Y8kJCb6EX02F6

Slide 6

Slide 6 text

= ● 自動ユニットテストにおける原則・パターンなどが体系的にまとめられている書 籍 ● ウェブページでも閲覧可能 ○ http://xunitpatterns.com/ ● 自動ユニットテストにおける「原則」について整理されていたり ○ Chapter 5 Principles of Test Automation ○ See also: xUnit Test Patternsから学ぶ12個のユニットテストの原則 by @hgsgtk ■ https://qiita.com/hgsgtk/items/a3186a250d36d3b224d9 ● 現在は英書のみ 6 『xUnit Test Patterns』

Slide 7

Slide 7 text

https://qiita.com/hgsgtk/items/a3186a250d36d3b224d9 7

Slide 8

Slide 8 text

= Test Smellsとは ● テストにまつわる問題の兆候 3つのカテゴリ分け ● Test Code Smells ○ 開発者やテスターがテストを読み書きする際の コーディングレベルのアンチパターン ● Behavior Smells ○ コンパイル時やテスト実行時 に出くわす ○ 無視するのが難しい “Smell”、テストの失敗がとても不都合な時に発生しうる ● Project Smells ○ テストコードを読んだり実行したりしない、プロジェクトマネージャや顧客が気づく ○ プロジェクト全体的な健全性の指標 取り除くには ● “Five Why’s” ○ 「問題の要因は何?」 →「その要因はなぜ発生した?」 → (repeat) 8 Test Smells

Slide 9

Slide 9 text

Code Smells One of Test Smells ● Obscure Test ● Conditional Test Logic ● Hard-to-Test Code ● Test Code Duplication ● Test Logic in Production 9

Slide 10

Slide 10 text

= ● ひと目で理解することが難しいテスト ● 自動化テストの2つの目的 ○ 「テスト対象がどう振る舞うべきか 」を示すドキュメント ○ それ自身が実行可能な仕様 ● メンテナンスコストの高いテストに繋がりうる ● いくつかの原因 ○ Eager Test ○ Mystery Guest ○ General Fixture ○ Irrelevant Information ○ Hard-coded Test Data ○ ...etc 10 Obscure Test

Slide 11

Slide 11 text

= ● 一つのテストケースでたくさん機能を検証しすぎているテスト ○ 例えば次のように1テストケースで複数Functionを検証している 11 Eager Test - a cause of Obscure Test - ● それによる弊害 ○ 一テストケースでの可読性の低下 ○ 一つが失敗すると後続が検証されない ● → Singile-Conditin Tests へ ○ 一つの機能を独立して検証する ○ 原因の特定をしやすくする

Slide 12

Slide 12 text

= ● 実行する・しないコードがテストに含まれている ○ ex. if分岐を含むテストコード ● テストコードは「テストする」ためにシンプルであるべき 12 Conditional Test Logic ● それによる弊害 ○ 「テストが本当に何をしようとしているのか」 を理解するのが難しい

Slide 13

Slide 13 text

= ● そもそもテストが難しいコード ○ ex. GUIコンポーネント・マルチスレッド・テストコード自体 ● →テスタビリティの良いコードへ ● いくつかの原因 ○ Highly Coupled Code ○ Asynchronous Code ○ Untestable Test Code ● See also Principles ○ “Write the Tests First” ○ ”Design for Testability” ○ “Minimize Untestable Code” ○ See also: https://qiita.com/hgsgtk/items/a3186a250d36d3b224d9 13 Hard-to-Test Code

Slide 14

Slide 14 text

= ● 他のクラスのテスト無しでテストできないクラス ● 原因 ○ 設計不足 ○ オブジェクト志向設計の経験不足 ○ 疎結合な構造への意識不足 ● →テスト駆動開発 ○ 自然と”密結合”を避けるようになる ○ See alos: “テストが辛いを解決するテスト駆動開発のアプローチ at PHPカンファレンス仙台 2019” by @hgsgtk ■ https://speakerdeck.com/hgsgtk/tesutokaxin-iwojie-jue-surutesutoqu-dong-kai-fa-fal seahuroti-at-phpkanhuarensuxian-tai-2019 ● →コードを分離するための手法 ○ Test Double (Test Stub or Mock Object) ● → オブジェクト指向設計を学ぶ ○ BASE社内勉強会「オブジェクト指向設計勉強会」 ■ 教材:『オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリ ケーションの育て方』 14 Highly Coupled Code - a cause of Hard-to-Test Code -

Slide 15

Slide 15 text

= ● 同じテストコードが何度も繰り返される ○ ex. setup fixture. assertion ● いくつかの原因 ○ Cut-and-Paste Code Reuse ○ Reinventing the Wheel Reinventing the Wheel ● 「車輪の再発明」 ● 便利な Test Utility があるならそれを使おう ○ ex. 使用フレームワークの Test Utility 15 Test Code Duplication

Slide 16

Slide 16 text

= ● テスト対象にテスト環境では動かないロジックがある ● それゆえ、テストをサポートするだけのロジックが含まれてしまう 16 Test Logic in Production ● 弊害 ○ 本番同等の動作をテストできていない ● → Test Specific Subclass の使用 ○ 特定の振る舞いだけを上書きしたクラス ● → Test Double の使用

Slide 17

Slide 17 text

Behavior Smells One of Test Smells ● Assertion Roulette ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests 17

Slide 18

Slide 18 text

= ● 同じテストメソッド内のどれかのアサーションが失敗する ● いくつかの原因 ○ Eager Test ■ 一つのテストでたくさんの機能を検証しすぎてる ○ Missing Assertion Message Missing Assertion Message ● アサーションの失敗原因を特定するメッセージの設定がない ● 参考になる考え方:Why does Go not have assertions? ○ https://golang.org/doc/faq#assertions ○ “thinking about proper error handling and reporting.” 18 Assertion Roulette

Slide 19

Slide 19 text

= ● 不安定なテスト ○ 時々通るし時々落ちる ● 弊害 ○ 失敗時のトラブルシューティングが難しい ■ ex. 順序に依存したテスト ■ → 原因特定用のTestSuiteを一時的に作ってデバッグする 19 Erratic Test

Slide 20

Slide 20 text

= ● 壊れやすいテスト ● テスト対象の変更に敏感に反応してテストが落ちる ● いくつかの原因 ○ Interface Sensitivity ○ Behavior Sensitivity ○ Data Sensitivity ○ Context Sensitivity Data Sensitivity ● テストデータの変更に敏感 ● Shared Fixture(共有されたフィクスチャ)の変更 ● →テスト実行前に状態チェック ○ 他の変更による影響を受けていないかを確認する 20 Fragile Test

Slide 21

Slide 21 text

Project Smells One of Test Smells ● Buggy Tests ● Developers Not Writing Tests ● High Test Maintenance Cost ● Production Bugs 21

Slide 22

Slide 22 text

= ● 開発者がテストを書かない ● いくつかの原因 ○ Not Enough Time ■ 過剰にタイトな開発スケジュール ○ Hard-to-Test Code ■ テストの難しいコード ○ Wrong Test Automation Strategy 22 Developers Not Writing Tests

Slide 23

Slide 23 text

Finish About this talk ● 「xUnit Test Patterns」はユ ニットテストの原則・パターン などを網羅的にまとめる ● 原則・パターンから自身のテス トコードを振り返ってみては 23

Slide 24

Slide 24 text

宣伝:PHPerKaigi 2019 24

Slide 25

Slide 25 text

?> 25