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
350
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
290
導入画面を実装したよ
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
570
プロジェクトの1ファイルに単体テストを書いてみた!〜本当にこれで合ってるの…??🤔〜
takattata
0
2.2k
Other Decks in Technology
See All in Technology
これでバッチリ!Azure マルチテナントアーキテクチャ設計のコツ/jat06
thara0402
0
150
大手企業のAIツール導入の壁を越えて:サイバーエージェントのCursor活用戦略
gunta
34
13k
Scale Security Programs with Scorecarding
ramimac
0
470
DevOpsDays Taipei 2025 - Opening Remarks
cheng_wei_chen
0
120
TechBull Membersの開発進捗どうですか!?
rvirus0817
0
480
CSSDay, Amsterdam
brucel
0
240
S3 Tables を図解でやさしくおさらい~基本から QuickSight 連携まで/s3-tables-illustrated-basics-quicksight
emiki
2
370
Azure Developer CLI と Azure Deployment Environment / Azure Developer CLI and Azure Deployment Environment
nnstt1
1
160
【ClickHouseMeetup】ClickHouseを活用したセキュリティログ解析AIエージェント『LogEater』とは
hssh2_bin
0
100
Bill One 開発エンジニア 紹介資料
sansan33
PRO
4
12k
從開發到架構設計的可觀測性實踐
philipz
0
180
Machine Intelligence for Vision, Language, and Actions
keio_smilab
PRO
0
520
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
41
7.3k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
470
Unsuck your backbone
ammeep
671
58k
Art, The Web, and Tiny UX
lynnandtonic
298
21k
Speed Design
sergeychernyshev
30
970
A Tale of Four Properties
chriscoyier
159
23k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
123
52k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Mobile First: as difficult as doing things right
swwweet
223
9.6k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.8k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
6
630
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分で書けたよ」