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
320
xUnit Test Patterns の序章
@社内LT大会_12月
※著作権的にアウトそうだったら消します
takattata
January 11, 2018
Tweet
Share
More Decks by takattata
See All by takattata
What's DDD?
takattata
5
750
Kotlinのコントリビュートに挑戦してみたよ!
takattata
3
270
導入画面を実装したよ
takattata
1
1.8k
AndroidXに移行しようと`してみた`!
takattata
2
670
Flutterテストことはじめ
takattata
1
710
Flutter
takattata
3
1.4k
ディープリンクを実装した
takattata
1
1.7k
introduce unit testing
takattata
1
490
プロジェクトの1ファイルに単体テストを書いてみた!〜本当にこれで合ってるの…??🤔〜
takattata
0
2k
Other Decks in Technology
See All in Technology
バッチ処理のSLOをどう設計するか
rynsuke
7
560
CI/CDがあたりまえの今の時代にAPIテスティングツールに求められていること / CI/CD Test Night #7
k1low
12
2.9k
オブジェクトのおしゃべり大失敗 メッセージングアンチパターン集 / messaging anti-pattern collection
ytake
0
330
Introduction to Jetpack Compose
pohjus
1
110
エンジニア候補者向け資料2024.03.28.pdf
macloud
0
2.9k
XRミーティング 2024-03-20
1ftseabass
PRO
0
100
データ品質をコード化! LINEヤフーのMLOpsを最適化する "ACP Data Quality" の紹介
lycorptech_jp
PRO
2
160
2023 Japan AWS Jr.Championsに選出されての振り返りとこれから
hiropy877
1
130
Kubeflow Pipelines v2 で変わる機械学習パイプライン開発
asei
4
340
どう買う?Azure
kuniteru
1
190
技術イベントはなんとかひねり出す 日経の技術広報の取り組み/techpr3
nishiuma
0
220
OpenTelemetry実践 はじめの一歩
taxin
0
310
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
421
63k
What the flash - Photography Introduction
edds
64
11k
Keith and Marios Guide to Fast Websites
keithpitt
407
22k
Product Roadmaps are Hard
iamctodd
43
9.6k
Building Better People: How to give real-time feedback that sticks.
wjessup
350
18k
Pencils Down: Stop Designing & Start Developing
hursman
115
11k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
18
1.7k
jQuery: Nuts, Bolts and Bling
dougneiner
57
7.1k
Why You Should Never Use an ORM
jnunemaker
PRO
50
8.6k
Atom: Resistance is Futile
akmur
258
25k
How STYLIGHT went responsive
nonsquared
92
4.7k
The Cost Of JavaScript in 2023
addyosmani
13
3.7k
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分で書けたよ」