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
xUnit Test Patterns の序章
Search
takattata
January 11, 2018
Technology
1
360
xUnit Test Patterns の序章
@社内LT大会_12月
※著作権的にアウトそうだったら消します
takattata
January 11, 2018
Tweet
Share
More Decks by takattata
See All by takattata
What's DDD?
takattata
5
890
Kotlinのコントリビュートに挑戦してみたよ!
takattata
3
300
導入画面を実装したよ
takattata
1
1.9k
AndroidXに移行しようと`してみた`!
takattata
2
720
Flutterテストことはじめ
takattata
1
800
Flutter
takattata
3
1.6k
ディープリンクを実装した
takattata
1
1.8k
introduce unit testing
takattata
1
580
プロジェクトの1ファイルに単体テストを書いてみた!〜本当にこれで合ってるの…??🤔〜
takattata
0
2.2k
Other Decks in Technology
See All in Technology
データプラットフォーム技術におけるメダリオンアーキテクチャという考え方/DataPlatformWithMedallionArchitecture
smdmts
5
610
Observability infrastructure behind the trillion-messages scale Kafka platform
lycorptech_jp
PRO
0
130
原則から考える保守しやすいComposable関数設計
moriatsushi
3
530
ハノーバーメッセ2025座談会.pdf
iotcomjpadmin
0
160
Fabric + Databricks 2025.6 の最新情報ピックアップ
ryomaru0825
1
120
Wasm元年
askua
0
130
変化する開発、進化する体系時代に適応するソフトウェアエンジニアの知識と考え方(JaSST'25 Kansai)
mizunori
1
200
フィンテック養成勉強会#54
finengine
0
160
登壇ネタの見つけ方 / How to find talk topics
pinkumohikan
3
350
2年でここまで成長!AWSで育てたAI Slack botの軌跡
iwamot
PRO
4
640
SalesforceArchitectGroupOsaka#20_CNX'25_Report
atomica7sei
0
140
BrainPadプログラミングコンテスト記念LT会2025_社内イベント&問題解説
brainpadpr
1
160
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Six Lessons from altMBA
skipperchong
28
3.8k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
790
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
RailsConf 2023
tenderlove
30
1.1k
The Pragmatic Product Professional
lauravandoore
35
6.7k
Building an army of robots
kneath
306
45k
Designing Experiences People Love
moore
142
24k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
Making the Leap to Tech Lead
cromwellryan
134
9.3k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Transcript
@takattata xUnit Test Patterns の序章
xUnit xUnitって何があるかご存知ですか?
JUnit(Java) SUnit(Smalltalk) NUnit(.Net) VbUnit(Visual Basic) CUnit(C) CppUnit(C++) PerlUnit(Perl) PyUnit(Python) HUnit(Haskell)
HttpUnit(HTTPによる通信を擬似的に行なう ) HtmlUnit(ウェブブラウザのエミュレータ ) … xUnitでなくても、テストの体系を学べる本 xUnit
Goals, Principles and Smells
The Patterns
脆弱なテスト(Fragile Test)の問題 4つの点において限界があることを知るのは重要 Introduction: Fragile Test Problem
Behavior Sensitivity システムの動作が変更された場合、修正された機能のテストは失敗する可能性が高い Introduction: Fragile Test Problem
Interface Sensitivity UIを介してテスト中のシステム内のビジネスロジックをテストするのは良くない (過去よくあった?) Introduction: Fragile Test Problem
Data Sensitivity テストは既にシステム内にあるデータの観点から定義された test fixture(=pre-conditions, before picture)があ るが、そのデータが変更された場合、多大な努力を払わないとテストは失敗する Introduction: Fragile
Test Problem
Context Sensitivity システム外の状態(デバイスや他アプリ, 日付等)のコンテキストの影響を受けるテストは、コンテキストを制御し ない限り、確定的に繰り返すことが困難 Introduction: Fragile Test Problem
Behavior Sensitivity Interface Sensitivity Data Sensitivity Context Sensitivity →これらを解決する為には、テストのフレームワークを効果的に使用する方法を学ばないといけない Introduction:
Fragile Test Problem
回帰テスト(regression testing) プログラムに手を加えたことによる影響を確認するテスト (=デグレしてないか確認する ) 仕様としてのテスト(tests as specification) TDD この本ではTDDの書き方ではなく、テストがどのようになっているかの観点から説明
test-driven, test-first, test-last開発のどれでも役に立つので、「開発プロセスには無関心」で書いている Introduction: type
Pattern =繰り返し問題に対する解決策 段階がある: 高いレベルの "strategy"パターン →より詳細な "design patterns" →最も詳細な "coding
idioms" へと進むためには、パターン間にリンケージが必要 Introduction: Patterns
Introduction: Patterns 3つのレベルで区別している - “Strategy” level patterns 大きな影響をもたらす Shared Fixture,
Fresh Fixtureを使用することで異なるテストデザインパターンに繋がる - Test “Design” level patterns 特定の機能のテストを書く時, テストロジックをどう整理するかに焦点をあてる ex.) Mock Object patternとか - Test “Coding Idioms” 特定のテストをコーディングする方法, 言語固有のもの
Introduction: Patterns vs Principles vs Smells Principles 選択したパターンはテスト自動化の”ゴール”(テスト自動化で望まれる結果が書かれている)に影響を受ける “ゴール”はパターンを良くすることについての信念体系を体系化する、多くの”原則”によってサポートされている(詳細 については該当の章を参照のこと)
Smells 使ってるパターンが持ってる、起こしがちな問題など
Introduction: Testing Terminology system under test(SUT) 「何をテストしているのか(whatever thing we are
testing)」の略 - unit testsを書く時、テストするクラス、メソッドのこと - customer testsを書く時、アプリ全体か主要なサブシステムのこと
- Unit Testは特定のテストに 関してのみSUT - Unit2 Testを見た時、Unit1 SUTはUnit2 SUTが使用する ため、dependend-on
component(DOC)の役割を する Testing Terminology
Refactoring A Test
Why Refactor Tests? テストは迅速な開発プロセスのボトルネックになるので、リファクタリングをした方が良い 実際に複雑なテストを簡単にする流れを見ながら、生産性の違いを感じてほしい 途中でいくつか重要なsmellsや、それを取り除くためのパターンを出していくよ
A Complex Test ・長い ・コメントが4行も ・ややこしい etc...
test conditionsを見ていこう まずここ、必ずfalseになることを期待しているなら、 Cleaning up the Verification Logic
失敗の呼び出しに変更しよう!直接言うべき これはExtract Method [Fowler]リファクタリング (Martin FowlerのRefactoring Improving the Design of
Existing Codeからメソッド名を引 用)
他にもある 何故こんなにアサーションが必要なんだ?
予想されるオブジェクトを作って、単一のアサーションを使おう これはPreserve Whole Object[Fowler] リファクタリング
でも、待って! なんで if 文がテストに出てくるの? Conditional Test Logic は排除していこう 幸運にも、今回はGuard Assertionが使える
if … else fail() … のところを同じ条件のアサーションに変えるだけ これをもっと短くしたいなら、 Extract Methodリファクタリングを使用して Custom
Assertionを定義しよう こうなる ↓
良き! 次は finallyブロック に注目しよう
そもそもこのコードには致命的な欠陥がある Cleaning up the Fixture Teardown Logic
もしdeleteObjectで失敗したら?のテストがな い! とはいえ、右の様なテストを管理するのはあり 得ない! この問題にはComplex Teardownがある 問題の根本を解決することはできないが、 tearDownメソッドに入れてコードを細分化しよ う
案1: “テスト間で分割されない ”Shared Fixtureを 使うことで、最初にオブジェクトを作らなくて 良くなる が、問題が2つ 1. 共有されたfixtureを介してやり取りす ることで、Unrepeatable
Test, Interacting Tests(不安定なテスト)を 含むtest smellsが多くなる 2. 共有されたfixtureから使われるオブ ジェクトへの参照がMystery Guests になる → 今回は却下
案2: Fresh Fixtureを使う 自動でGCされるメモリ内のfixtureを使う が、問題が1つ 1. 作成するオブジェクトが永続的なもの (DBに保存されているなど )では機能しな い
→ 今回は採用 実現方法: テスト自動化フレームワークに、作成したオブ ジェクトを登録する方法を追加して、削除する
テストクラスに ・オブジェクトを確保しておくリスト ・追加する関数 ・削除する関数 を準備して、使う
良くなった が、まだいける たとえば、変数を初期化する必 要はあるだろうか? これはfinallyブロックのためだっ たから、宣言と初期化を合体さ せよう!
None
Cleaning up the Fixture Setup Extract Methodリファクタリングを使用してCreation Methodを定義しよう オブジェクトを作成して、registerTestObjectを呼び出す関数をそれぞれ作ろう 利点:
読みやすくなる + カプセル化されるからコンストラクタが変更された時にメンテナンスしやすい
まだ問題がいくつかある 1. fixtureが予想している結果とどう関連しているか分かりづらい 2. Hard-Coded Test Dataを使っている (Unrepeatable Test, Interacting
Tests, Test Run Warが起こる可能性が出る ) 解決法: 各テストに固有の値を作って、その値を元にテスト用に作成したオブジェクトで使う (=Anonymous Creation Method) ←今までの引数は関数内に値を移した Addressも → customerで 使いたいだけ createACustomer関数 内でやれば良いね? (Extract Method再び)
これで、テストで検証しているロジックに影響するものだけになった でも、まだ2回繰り返されているハードコーディングされたテストデータがある Replace Magic Number with Symbolic Constantリファクタリングで、 数字の意味を明確にしよう
ついでに、計算が分かりにくいので Introduce Explaining Variableリファクタリングで文書化してみた このコードはTests as Documentationの役割を完全に満たしている(テストの”ゴール”に関わる) The Cleaned Up
Test
Writing More Tests Q: 毎度こんなに色々書くの ?? A: 再利用出来る Test Utility
Methods があるし、 アプリのテストの為に Higher Level Language を定義している 「先ほどの内容をUtilityで書き 換えたけど、2分で書けたよ」