xUnit Test Patterns - Chapter16

2,686 views
2,612 views

Published on

handout for xUnit Test Patterns Reading Group Japan

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,686
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

xUnit Test Patterns - Chapter16

  1. 1. Chapter 16. Behavior Smells
  2. 2. Smells in This Chapter ● Assertion Roulette ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  3. 3. Assertion Roulette
  4. 4. Assertion Roulette (1) ● 初出 ● XP2001 “Refactoring Test Code” ● Symptoms ● テスト失敗時に、どの assertion が失敗したのかよ く分からない ● Impact ● CI 中にテストが Assertion Roulette が発現した場 合には解析が難しい。手元のマシンで再現できない 時はさらに時間を食うことになる
  5. 5. Assertion Roulette (2) ● Causes ● Eager Test – ひとつのテストで機能を検証しすぎている ● Missing Assertion Message – アサーションメッセージが無い
  6. 6. Smells in This Chapter ● Assertion Roulette ● Eager Test ● Missing Assertion Message ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  7. 7. Eager Test (1) ● Symptoms ● ひとつのテストが SUT の複数のメソッドをテスト している ● ひとつのテストが SUT の同じメソッドを fixture setup logic や assertion などバラバラな場所から 複数回呼んでいる ● テスト技術者がテストフレームワークを改造して assertion が失敗してもその行以降を実行させよう とする
  8. 8. public void testFlightMileage_asKm2() throws Exception { //set up fixture //exercise constructor Flight newFlight = new Flight(validFlightNumber); //verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); //set up mileage     newFlight.setMileage(1122); //exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); //verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); //now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } }
  9. 9. Eager Test (2) ● Root Cause ● テストの中で多くの検証を行って (意図的であるに しろ無いにしろ) テストの数を最小にしようとする こと – 手動テストにおいては一度にたくさんの要素をテストす るのは良いこととされているが、完全自動化されたテス トにおいては悪手 ● 多くのステップを必要とする Customer Test を xUnit を使って行おうとすること
  10. 10. Eager Test (3) ● Possible Solution ● Single-Condition Test (p45) に分解する – Extract Method [Fowler] – ひとつひとつのテスト要素毎にコピーして不要な部分を 削除 ● Creation Method (p415) – Fixture を setup したり SUT を特定の状態にする部分 をメソッドに切り出す – Lean on Compiler [WEwLC] 使おう
  11. 11. Eager Test (4) ● Customer Test を xUnit で行っている場合 – テストシナリオが進むに応じて複雑な状態がテスト内で 作り出されていく – テスト後半部分を切り出すためには複雑な状態の setup が必要なので、なんらかの手段を講じる必要がある ● Back Door Setup (p327) を使ってテスト後半部分 の setup を行えればテストを分割できる – Defect Localization につながる – テストを短くしていけば Communicate Intent (p41) へ
  12. 12. Smells in This Chapter ● Assertion Roulette ● Eager Test ● Missing Assertion Message ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  13. 13. Missing Assertion Message (1) ● Symptoms ● テスト失敗時に、どの assertion が失敗したのか よく分からない
  14. 14. Missing Assertion Message (2) ● Root Cause ● Assertion Method (p362) が – 同じ Assertion Method が複数回使われている – Assertion Message (p370) 無しで書かれている ● コマンドラインからテストを実行したり、開発環境 とテストコードが統合されていない時にどこで失敗 したか分からず困る
  15. 15. public void testInvoice_addLineItem7() { LineItem expItem = new LineItem(inv, product, QUANTITY); //Exercise inv.addItemQuantity(product, QUANTITY); //Verify List lineItems = inv.getLineItems(); LineItem actual = (LineItem)lineItems.get(0); assertEquals(expItem.getInv(), actual.getInv());     assertEquals(expItem.getProd(), actual.getProd()); assertEquals(expItem.getQuantity(), actual.getQuantity()); } 失敗した時に見分けはつくか? Meszaros says: 同じタイプの Assertion Method を使うときは Assertion Message を書いておくこと t-wada says: Assertion Message も Smell では?
  16. 16. Missing Assertion Message (3) ● Possible Solution ● GUI のある IDE の場合はスタックトレースをクリックして 飛んで、ブレークポイントつけて再実行できたりする ● コマンドラインで実行している場合には GUI ランナーや IDE で実行して落ちている assertion を見つけよう ● それらもダメな場合は行番号を追ったり、もっと深追いし なければならない ● そんな頑張らずに、数字でもいいから Assertion Message 入れよう (そういえばひがさんはそうしてた)
  17. 17. Smells in This Chapter ● Assertion Roulette ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  18. 18. Erratic Test
  19. 19. erratic 【名】 1. 変人、奇人 2. 《地学》迷子石◆【同】erratic boulder 【形】 1. 〔人の言動が〕とっぴな、風変わりな、異常な、常軌を逸した 2. 一貫性のない、不安定な、一定しない、出来不出来がある、不 規則な 3. 《地学》〔石などが氷河で〕漂移した
  20. 20. Erratic Test (1) ● 成功したり失敗したり、動きが一定でない ● Symptoms ● いつ実行したかや誰が実行したかによってテストの 結果が異なる ● 同じ Test Runner で実行しても結果がバラバラな ことがある
  21. 21. Erratic Test (2) ● Impact ● いつも Test Suite を緑にしたいので Erratic Test を suite から外し、Lost Test (p268) につながる ● Suite に入れたままにしたらしたで、他のテストで 赤が出たときに気づかなかったりする
  22. 22. Erratic Test (3) ● Troubleshooting Advice ● 原因がいろいろあるので手強い ● 簡単に見つからない場合にはデータを定期的に採っ て調べる必要がある – どこで成功し、どこで失敗したか – 全部のテストを実行したのか、一部を実行したのか – 同じ行を何度も実行した時に振る舞いが変わったか – 複数の Test Runner を同時に実行した時に振る舞いが 変わったか
  23. 23. Erratic Test (4) ● Troubleshooting Advice ● 原因がいろいろあるので手強い ● 簡単に見つからない場合にはデータを定期的に採っ て調べる必要がある – どこで成功し、どこで失敗したか – 全部のテストを実行したのか、一部を実行したのか – 同じ行を何度も実行した時に振る舞いが変わったか – 複数の Test Runner を同時に実行した時に振る舞いが 変わったか ● データが採れたら次のページの切り分け図へ
  24. 24. Erratic Test (5)
  25. 25. Erratic Test Causes ● Assertion Roulette ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  26. 26. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  27. 27. Interacting Tests (1) ● テストが他のテストに何らかの形で依存してい る ● バリエーション ● Interacting Test Suite ● Lonely Test
  28. 28. Interacting Tests (2) ● Symptoms ● 独立して動かすときには成功しているテストが以下 の状況下で失敗する – 他のテストが suite に追加 / 削除されたとき – Suite の他のテストが失敗 / 成功したとき – テスト自身、もしくは他のテストのファイル名が変更さ れたとき – Test Runner の新バージョンがインストールされたとき
  29. 29. Interacting Tests (3) ● Root Cause ● 多くの場合、 Shared Fixture (p317) を使ってい てかつ他のテストの (Shared Fixture への) 出力に 依存しているために発生する ● 二つの側面から説明できる – The mechanism of interaction – The reason of interaction
  30. 30. Interacting Tests (4) ● The Mechanism of interaction ● テスト (インスタンス) の寿命より長いものを使う ときに起こる – データベース – static 変数 ● やめておいたほうがいいもの – Singleton [GoF] – Registry [PofEAA]
  31. 31. Interacting Tests (5) ● The Reason of interaction ● 他のテストの fixture setup phase で作られる fixture に依存している ● 他のテストが SUT に与える変化に依存している ● 相互排他に行うべきテストを同時に行うことによる 競合
  32. 32. Interacting Tests (5) ● 依存関係が終わるとき ● 依存している他のテストが – suite からいなくなる – SUT を変化させなくなる – SUT を変化させる際に失敗するようになる – 改名などにより、テスト実行の順番が後ろになる ● 競合が始まるとき ● 競合しているテストが – suite に加わる – 初めて成功した時点 – テスト実行の順番が前になったとき
  33. 33. Interacting Tests (6) ● テスト対象自体は正しいのに失敗するようにな るので、 “false-positive” になる。 ● 一般論としてテスト実行順に依存するのは良く ない ● xUnit ファミリーは実行順を保証しない ● TestNG は保証する
  34. 34. Interacting Tests (7) ● Possible Solution ● Fresh Fixture (p311) – もっとも望ましい ● Shared Fixture を使いたい場合は – Immutable Shared Fixture ● 他のテストが作成するオブジェクトに依存している 時は – 両方のテストに Lazy Setup (p435) を書く ● コードが重複する場合は – Creation Method (p415) – Test Helper (p643)
  35. 35. Interacting Tests (8) ● Possible Solution (Cont'd) ● テストで作成されたものが残っていることによる競 合には – Automated Fixture Teardown (p503) ● テストの依存を見つける方法 ● いつもと違う順番で実行してみる – すべてのテストを逆順に実行してみる ● 普段から常にバラバラの順番でテストを実行するよ うにしておくと事故を防げて良い
  36. 36. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  37. 37. Interacting Test Suites (1) ● Symptoms ● Suite 単体では成功するが、 Suite の Suite とい う構成にすると失敗する ● Root Cause ● よくあるのは、同じリソースを Suite が作成しよ うとし、後から実行された Suite のほうが失敗す るケース
  38. 38. Interacting Test Suites (2) ● 探すには ● 失敗したテストを見る ● それでも分からない時には – 成功している方の Suite からテストを一つずつ取り除く ● 失敗しなくなったときに取り除いたテストが依存元 ● 場所はどこか – Shared Fixture – Test Method 内 – Setup method – Test Utility
  39. 39. Interacting Test Suites (3) ● Root Cause (Cont'd) ● 依存しあっているのは一つのテストとは限らない ● テストケースではなく Suite Fixture Setup や Setup Decorator が引き金となっているかもしれ ない ● NUnit についてまたいろいろ書いているが割愛
  40. 40. Interacting Test Suites (4) ● Possible Solution ● 一番いいのは全部 Fresh Fixture にすること ● Fresh Fixture にするのが難しければ Immutable Shared Fixture ● データベースに残っている残骸が問題なら Automated Teardown
  41. 41. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  42. 42. Lonely Test (1) ● Interacting Tests の特殊例 ● Suite の一部としては実行成功するが、単独で は動かない ● 他のテストの触った Shared Fixture に依存してい る – Chained Tests – Suite-level fixture setup
  43. 43. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  44. 44. Resource Leakage (1) ● Symptoms ● テストがだんだん遅くなり、ついには失敗しだすように なる ● Test Runner / SUT / Database Sandbox(p650) をク リーンアップするとテストが通るようになる ● Root Cause ● 有限リソースをテストが消費し、それの開放に失敗して いる ● テストがどんどん遅くなる ● テストを連続して続けるとリソースが使い尽くされ、後 続のテストが失敗し始める
  45. 45. Resource Leakage (2) ● Root Cause (Cont'd) ● SUT がリソースの開放に失敗している – これが判明したら、直すのも難しくない ● テストが fixture setup でリソースを消費し、開 放に失敗している
  46. 46. Resource Leakage (3) ● Possible Solution ● SUT がリソースを開放していないとき – テストは仕事をきちんとしているので SUT のバグを直 すべし ● テスト失敗時にリソース開放に失敗している場合 – Guaranteed In-line Teardown (p509) – Automated Teardown ● リソースプールのサイズを 1 にするのがいい ● 問題がある場合にはテストがすぐ失敗するようにな り、気づきやすい
  47. 47. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  48. 48. Resource Optimism ● Symptoms ● ある環境下で動くテストが他の環境下で失敗する ● Root Cause ● ある環境に存在するリソースが他の環境で不在 ● Possible Solution ● 可能なら、 Fresh Fixture をテストから毎回作成す るようにする – 相対パスを使ってファイルを生成するなど ● 外部リソースを使わなければならない場合には SCM に入れることも視野に入れる
  49. 49. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  50. 50. Unrepeatable Test (1) ● Symptoms ● あるテストがテスト群の先頭にある場合はテストが 成功し、後続にある場合は失敗する。もしくはその 逆。 – Pass-Fail-Fail – Fail-Pass-Pass
  51. 51. Unrepeatable Test (2) ● Root Cause ● (意図の有無に関わらず) Shared Fixture の使用 – Prebuilt Fixture を使っている場合にはDatabase ● Sandbox を使っていても、同一の開発者が同一の テストランナーを使ったときは発生する ● Lazy Setup を使っている場合には、 fixture が class 変数を使いつづけたりする
  52. 52. Unrepeatable Test (3) ● Possible Solution ● Fresh Fixture! – Database Sandbox すら生ぬるい ● Fake Database (p551) ● 共有 Database を使わなければならない場合には Distinct Generated Values (p723) ● Automated Teardown
  53. 53. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  54. 54. Test Run War (1) ● Symptoms ● 一人でテストを実行する時はテストが成功するが、 複数人が同時にテストを実行すると失敗する ● Impact ● カットオフ間近に発生しがちだからイライラする! ● 「テストが落ちたら最後の変更を疑え」ルールが機 能しなくなる
  55. 55. Test Run War (2) ● Root Cause ● Shared Fixture (Database) – 行の UPDATE / DELETE / SELECT などの競合 – 悲観ロック ● Shared Fixture (File) – 既に他の人がファイルを開いているなど
  56. 56. Test Run War (3) ● Possible Solution ● Fresh Fixture (★何回目?) ● Test Runner 毎に Database Sandbox を使う – しかしこれではまだ Shared Fixture 経由の Interacting Test は解決しない ● Immutable Shared Fixture – Test の変更が若干必要かも ● データベースに残る残骸が問題なら Automated Teardown – Test Run War の根本解決にはならないが、確率が減る
  57. 57. Erratic Test Causes ● Erratic Test ● Interacting Tests ● Interacting Test Suites ● Lonely Test ● Resource Leakage ● Resource Optimism ● Unrepeatable Test ● Test Run War ● Nondeterministic Test
  58. 58. Nondeterministic Test (1) ● Symptoms ● テストがランダムに失敗する – 人や環境、同時実行にも関係なさそう ● 複数の Nondeterministic Test が suite にあると 問題判別が難しい ● Impact ● デバッグに時間がかかりすぎるし、イライラする
  59. 59. Nondeterministic Test (2) ● Root Cause ● テスト毎に異なる値を使うことによって発生する – ただし、異なる値を使うこと自体は悪いことではない。 (例 : Distinct Generated Value) – テスト対象アルゴリズムへの入力にランダムな値を使う ときに問題が発生する ● Integer の負数や臨界値など ● 長さ限界の文字列など ● ランダム値を使うことは悪くないように思えるが、 カバレッジへの信頼とテストの repeatabilty が下 がる
  60. 60. Nondeterministic Test (3) ● Root Cause (Cont'd) ● Conditional Test Logic の使用がテストにランダ ムさをもたらす – テスト毎にテスト実行パスが異なる
  61. 61. Nondeterministic Test (4) ● Possible Solution ● Conditional Test Logic を取り除いて Linear に実 行されるようにする ● ランダム値の使用を止めて deterministic な値を 使うようにする ● 臨界値や同値分割を使う ● テストが重複し始めたら – Parameterized Test (p607) – Data-Driven Test (p288)
  62. 62. Smells in This Chapter ● Assertion Roulette ● Erratic Test ● Fragile Test ● Frequent Debugging ● Manual Intervention ● Slow Tests
  63. 63. Fragile Test
  64. 64. fragile 【形】 1. 壊れやすい、もろい、割れやすい、脆弱な、傷 (が)付きやすい、駄目になりやすい、危うい、軽 い、か弱い、はかない、きゃしゃな 2. 実質のない、不十分な 3. 束の間の、逼迫した 4. 虚弱な、元気がない、調子が悪い
  65. 65. Fragile Test (1) ● Symptoms ● 全然関係ないと思っていた部分の修正で、テストが コンパイル/実行に失敗し始める – ときには production code に手を触れていないのに失敗 し始めることも ● テスト自動化に頑張っていればいるほど、”four sensitivities” (4 つの過敏症) に引っかかりやすく なる
  66. 66. Fragile Test (2) ● Impact ● 変更を行う際にあちこちのテストを見なければなら ないため、テストのメンテナンスコストが上がる ● Incremental delivery を行う XP のようなプロセ スでは、テストのメンテナンスコスト増は致命傷に なりうる
  67. 67. Fragile Test (3) ● Troubleshooting Advice ● 「落ちたテストに共通点は無いか?」と自問しよう – テストと SUT の結合点が見えてくる ● 4 sensitivities ● Interface Sensitivity – コンパイルに失敗する – 動的型付け言語では型非互換ランタイムエラー ● Behavior Sensitivity – 直前の変更を戻したらテストが通るようになる
  68. 68. Fragile Test (4) ● Troubleshooting Advice (Cont'd) ● Data Sensitivity – 直前のコード変更を戻してもテストが失敗する ● Shared Fixture を使っている or Fixture setup code を変更し た ● Context Sensitivity – 直前のコード変更を戻してもテストが失敗する ● テストコードもテストデータもいじってない
  69. 69. Fragile Test (5) ● Troubleshooting Advice (Cont'd) ● Data Sensitivity – 直前のコード変更を戻してもテストが失敗する ● Shared Fixture を使っている or Fixture setup code を変更し た ● Context Sensitivity – 直前のコード変更を戻してもテストが失敗する ● テストコードもテストデータもいじってない
  70. 70. Fragile Test (6)
  71. 71. Fragile Test (7) ● Causes ● Indirect Testing – SUT に他のオブジェクトを介してアクセスしている ● Eager Tests – テストで検証をしすぎている ● SUT の結合度が強すぎることの現れ – そもそも小さい単位でテストするのが難しい SUT なの かもしれない (Hard-to-Test Code) – Test Doubles を使い慣れていないだけかもしれない
  72. 72. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  73. 73. Interface Sensitivity ● Symptoms ● SUT が変更されるとテストのコンパイル/実行に失 敗する – 静的型付け言語の場合はテストコンパイル失敗 – 動的型付け言語の場合はテスト実行失敗 – (変種) GUI 経由で Recorded Test を行っている場合 は、 UI 変更でテスト実行に失敗するとか
  74. 74. Interface Sensitivity (2) ● Possible Solution ● 原因はわかりやすいことが多い – コンパイル/テスト失敗する場所が問題箇所 – 結局変更点が引き金になっていることが多い ● 内部で使われる interface の場合には SUT API Encapsulation – テスト用の Higher-Level Language (p41) を組む ● Test Utility Methods ● Creation Methods ● “公布済み interface” の場合にはきちんと管理する しかない
  75. 75. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  76. 76. Behavior Sensitivity ● Symptoms ● SUT が変更されると関係ない部分のテストの実行に失 敗する ● Root Cause ● テストが失敗する事自体は悪くない。自動テストはそ のためにある。 ● Behavior Sensitivity になるのは、関係ないと思って いたテストの以下の部分が失敗するとき – Pre-test state setup (fixture setup) – Post-test state verification – Tear down (fixture teardown)
  77. 77. Behavior Sensitivity (2) ● Possible Solution ● Fixture setup に失敗しているとき – Creation Method ● State Verification に失敗しているとき – Custom Assertion – Verification Method ● (fixture teardown が無いが…たぶん) – Test Utility Method – Delegated Teardown
  78. 78. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  79. 79. Data Sensitivity ● Symptoms ● テストデータが変更されるとテストの実行に失敗す る – 既存テストデータの追加、更新、削除 – Standard Fixture のセットアップコードが変更された – テスト実行前に Shared Fixture が変更されている ● Root Cause ● データが変わっている! – 検索に余計に引っかかるとか – 無くなっているとか
  80. 80. Data Sensitivity (2) ● Possible Solution ● 多くの場合 result verification で発生する – Verification logic を見直す ● 一番良いのは Fresh Fixture ● Database Partitioning Scheme ● Delta Assertions
  81. 81. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  82. 82. Context Sensitivity ● Symptoms ● 成功していたテストが突然失敗し始める – Erratic Test との違いは、再現性があること ● Root Cause ● 時刻や日付に依存している ● SUT が他システムや OS に依存している ● 本当にユニットテストになっているか確認しよう。テス ト範囲が広すぎて Context Sensitivity に陥っていない か ● 広すぎると誰かが DOC を変更しただけでもテストは失 敗する
  83. 83. Context Sensitivity (2) ● Root Cause (Cont'd) ● 時刻や日付に依存しているコードがあるか ● 他システムからの入力に依存しているコードがある か ● 実は問題が発生したりしなかったりするようなら Erratic Test の知識を生かすべし ● Possible Solution ● Test Stub (p529) に置き換える ● 時刻依存なら Virtual Clock [VCTP] に置き換える – (Fowler の FakeClock もみてみよう)
  84. 84. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  85. 85. Overspecified Software ● テストが SUT がどう振る舞うべきかについて 「過剰に」記述されている ● Test Double を使った Behavior Verification でよ く発生する ● Mock Object の使いすぎ ● 原因は「What」ではなく「How」をテストで 記述してしまっていること ● 実装依存になりすぎている ● Use the Front Door First !! (p40)
  86. 86. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  87. 87. Sensitive Equality ● オブジェクトを文字列に変換して expected と actual を比較している ● 関係ない部分の比較で失敗しやすい ● interface の semantics が変更されていると いう意味では Interface Sensitivity とも言え る(?) ● オブジェクトの文字列変換による比較は災いの 素 (Gerard) ● まさーるさんは文字列比較を奨めていたが…
  88. 88. Fragile Test Causes ● Fragile Test ● Interface Sensitivity ● Behavior Sensitivity ● Data Sensitivity ● Context Sensitivity ● Overspecified Software ● Sensitive Equality ● Fragile Fixture
  89. 89. Fragile Fixture ● 新しいテストのために Standard Fixture を編 集したら、全然違うテストが失敗した ● Data Sensitivity や Context Sensitivity の変種 ● Fixture の性質の違い
  90. 90. ご清聴 ありがとう ございました

×