Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
xUnit Test Patterns の序章
Search
takattata
January 11, 2018
Technology
1
370
xUnit Test Patterns の序章
@社内LT大会_12月
※著作権的にアウトそうだったら消します
takattata
January 11, 2018
Tweet
Share
More Decks by takattata
See All by takattata
What's DDD?
takattata
5
910
Kotlinのコントリビュートに挑戦してみたよ!
takattata
3
300
導入画面を実装したよ
takattata
1
2k
AndroidXに移行しようと`してみた`!
takattata
2
730
Flutterテストことはじめ
takattata
1
820
Flutter
takattata
3
1.6k
ディープリンクを実装した
takattata
1
1.9k
introduce unit testing
takattata
1
580
プロジェクトの1ファイルに単体テストを書いてみた!〜本当にこれで合ってるの…??🤔〜
takattata
0
2.3k
Other Decks in Technology
See All in Technology
会社紹介資料 / Sansan Company Profile
sansan33
PRO
11
390k
Identity Management for Agentic AI 解説
fujie
0
120
2025-12-18_AI駆動開発推進プロジェクト運営について / AIDD-Promotion project management
yayoi_dd
0
120
AI駆動開発の実践とその未来
eltociear
1
320
多様なデジタルアイデンティティを攻撃からどうやって守るのか / 20251212
ayokura
0
490
WordPress は終わったのか ~今のWordPress の制作手法ってなにがあんねん?~ / Is WordPress Over? How We Build with WordPress Today
tbshiki
2
840
生成AI活用の型ハンズオン〜顧客課題起点で設計する7つのステップ
yushin_n
0
250
100以上の新規コネクタ提供を可能にしたアーキテクチャ
ooyukioo
0
100
Lookerで実現するセキュアな外部データ提供
zozotech
PRO
0
170
シニアソフトウェアエンジニアになるためには
kworkdev
PRO
3
190
GitHub Copilotを使いこなす 実例に学ぶAIコーディング活用術
74th
3
3.5k
初めてのDatabricks AI/BI Genie
taka_aki
0
210
Featured
See All Featured
More Than Pixels: Becoming A User Experience Designer
marktimemedia
2
250
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
280
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
1
1.3k
Context Engineering - Making Every Token Count
addyosmani
9
540
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.5k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
740
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
20
How to make the Groovebox
asonas
2
1.8k
Marketing to machines
jonoalderson
1
4.3k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.1k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.3k
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分で書けたよ」