テスト駆動開発(TDD) in .NET

2,752 views

Published on

2016/5/7開催 Niigata.NET 2.0 でのテックトーク資料
https://ngtnet.doorkeeper.jp/events/43037

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,752
On SlideShare
0
From Embeds
0
Number of Embeds
2,353
Actions
Shares
0
Downloads
3
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

テスト駆動開発(TDD) in .NET

  1. 1. テスト駆動開発(TDD) in .NET 2016/5/7 - #ngtnet TAKANO Sho(高野 将)/ @masaru_b_cl
  2. 2. 自己紹介 某SIerで働くDeveloper そのかたわら執筆業も #ngtnet 2
  3. 3. 今日お話すること テスト駆動開発(TDD)とは? .NET開発におけるTDD TDDの実例 TDDの指針 #ngtnet 3
  4. 4. テスト駆動開発(TDD)とは? #ngtnet 4
  5. 5. テスト駆動開発(TDD)とは? ケント・ベックが提唱した開発手法 #ngtnet 5 テスト駆動開発入門(ケント・ベック著、ピアソンエデュケーション刊) http://www.amazon.co.jp/dp/4894717115 “「動作するきれいなコード」、 ロン・ジェフリーズの この簡潔な言葉は、 TDD(テスト駆動開発)の目標である。 動作するきれいなコードは、 あらゆる理由で価値がある。 絶版
  6. 6. TDDの進み方 #ngtnet 6 TDD のこころ @ OSH2014 http://www.slideshare.net/t_wada/osh2014-sprit-of-tdd
  7. 7. TDDの進み方 #ngtnet 7 着実な道をいく
  8. 8. TDDのサイクル 1. 次の目標を考える 2. その目標を示すテストを書く(テストファースト) 3. そのテストを実行して失敗させる(Red) 4. 目的のコードを書く 5. 2で書いたテストを成功させる(Green) 6. テストが通るままで リファクタリングを行う(Refactoring) 7. 1~6を繰り返す #ngtnet 8 TDD のこころ @ OSH2014 http://www.slideshare.net/t_wada/osh2014-sprit-of-tdd
  9. 9. TDDのサイクル 小さく素早く回す ≒ フィードバックを早く得る #ngtnet 9
  10. 10. TDDの黄金の回転 #ngtnet 10 TDD のこころ @ OSH2014 http://www.slideshare.net/t_wada/osh2014-sprit-of-tdd
  11. 11. 動作するきれいなコード Clean code that works #ngtnet 11 Beautiful
  12. 12. 動作するきれいなコード #ngtnet 12 新装版 リファクタリング (マーチン・ファウラー著、オーム社刊) https://estore.ohmsha.co.jp/titles/978427405019P リーダブルコード (ダスティン・ボズウェル、 トレバー・フォシェ著、O’REILLY刊) https://www.oreilly.co.jp/books/9784873115658/
  13. 13. 動作するきれいなコード #ngtnet 13 C# 実践開発手法 (ゲイリー・マクリーン・ホール著、 日経BP社刊) http://ec.nikkeibp.co.jp/item/books/P98470.html Head First デザインパターン (エリック&エリザベス・フリーマン、 キャシー・シエラ、バートベイツ著、 O’REILLY刊) https://www.oreilly.co.jp/books/4873112494/
  14. 14. 動作するきれいなコード #ngtnet 14 .NETのクラスライブラリ設計 (Krzysztof Cwalina、Brad Abrams著、日経BP社刊) http://ec.nikkeibp.co.jp/item/books/P98470.html
  15. 15. TDDの目的 #ngtnet 15
  16. 16. TDDの目的 テストは手段であり目的ではない 動作するきれいなコードは 変化に対応しやすい 変化に対応しやすいということは 不安が少ない 不安の少ない状態≒健康 #ngtnet 16
  17. 17. TDDの目的 健康なコード 健康な体 健康なチーム #ngtnet 17
  18. 18. .NET開発におけるTDD #ngtnet 18
  19. 19. .NET開発におけるTDD テスティングフレームワーク およびサポートツール ソリューション構成 テストコード テスト実行 #ngtnet 19
  20. 20. テスティングフレームワーク MSTest VS標準搭載でお手軽さNo.1 NUnit *Unit系正統派で手堅い xUnit.net 新たに見直された次世代フレームワーク #ngtnet 20
  21. 21. テスティングフレームワーク 個人的オススメは2つのどちらか MSTest 入門には最適 NUnit 情報が多い #ngtnet 21
  22. 22. サポートツール テストアダプター VS上でMSTest以外も実行可能にする拡張 NUnit3 Test Adapter https://visualstudiogallery.msdn.microsoft.com/0da0f6bd-9bb6-4ae3-87a8-537788622f2d xUnit.net runner for Visual Studio https://visualstudiogallery.msdn.microsoft.com/463c5987-f82b-46c8-a97e-b1cde42b9099 #ngtnet 22
  23. 23. サポートツール Chaining Assertion A.Is(B)でテストが書ける #ngtnet 23 Chaining Assertion – CodePlex http://chainingassertion.codeplex.com/
  24. 24. ソリューション構成 複数プロジェクトで構成する テスト対象プロジェクト アプリケーション(*.exe)or クラスライブラリ(*.dll) (テスト対象の型はpublic or internal(※)に) テストプロジェクト MSTest : 単体テストプロジェクト 他 : クラスライブラリ + テスティングフレームワークへの参照 #ngtnet 24 ※アセンブリ属性InternalsVisibleToの設定が必要
  25. 25. テストコード #ngtnet 25 using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Test.MSTest { [TestClass] public class UnitTest1 // テストクラス { [TestInitialize] public void SetUp() { /* テスト初期処理 */ } [TestCleanup] public void TearDown() { /* テスト後処理 */ } [TestMethod] public void TestSomething() { // テスト主処理 “実際の値”.Is(“期待する値"); } } } MSTest+Chaining Assertionのテストコード
  26. 26. テスト実行 テスト エクスプローラーで結果表示 #ngtnet 26
  27. 27. TDDの実例 #ngtnet 27
  28. 28. TDDの実例 FizzBuzzをTDDで作成してみます #ngtnet 28 • 1から100までの整数を順番に出力する • ただし、 • 値が3の倍数の場合は”Fizz”を • 値が5の倍数の場合は”Buzz”を • 値が3と5の公倍数の場合は”FizzBuzz”を • それぞれ表示すること
  29. 29. 設計 ざっと設計しToDoリストを作成する 正の整数の場合、その数値を文字列で返す 3の倍数の場合、”Fizz”を返す 5の倍数の場合、”Buzz”を返す 3と5の公倍数の場合、”FizzBuzz”を返す 0以下の場合、引数エラーにする #ngtnet 29
  30. 30. 最初のテスト作成 ToDoリストから一つ選び、 最初の失敗するテストを作成する 例)引数が1の場合、”1”を返す 自分が最初のユーザーとなり、 使いやすいAPI設計を考える 型名、メソッド名、引数や戻り値の型、etc… #ngtnet 30
  31. 31. 最初のテスト失敗 テストを実行して失敗することを確認する 正しく失敗することを担保するため コンパイルエラーも失敗に含める #ngtnet 31
  32. 32. 仮実装(Fake It) テストが成功する最速の実装を行う 定数やリテラルを使っても良い 例)”1”を返す テストの妥当性を担保する #ngtnet 32
  33. 33. 最初のテスト成功 テストが成功することを確認する #ngtnet 33
  34. 34. リファクタリング テストが成功する状態を保ったまま、 コードを整理する テストコードを整えることも含む 例)名前付き引数の名前を削除する #ngtnet 34
  35. 35. 次の失敗するテストを追加する プログラミングを先にすすめるため、 小さな一歩となるテストを追加する 三角測量を行うこともある 1つの実装に対して2つのテストで三角 例)引数が2の場合、”2”を返す #ngtnet 35
  36. 36. すべてのテストを実行 追加したテストのみ失敗することを確認する 他のテストも失敗する =良くない設計の臭い 仕様でなく実装に対してテストしている 責務分割が不十分 など #ngtnet 36
  37. 37. テストが成功するまで修正 仮実装の定数やリテラル等を 引数、変数に置き換える 例)引数を文字列にして返す #ngtnet 37
  38. 38. リファクタリング 再びリファクタリング fizzBuzzer変数をフィールドにし、 SetUpメソッドを導入する 冗長なテストを統合、削除する #ngtnet 38
  39. 39. ToDoリストを更新する 完了したものを消す 1以上の場合、その数値を文字列で返す 3の倍数の場合、”Fizz”を返す 5の倍数の場合、”Buzz”を返す 3と5の公倍数の場合、”FizzBuzz”を返す 0以下の場合、引数エラーにする #ngtnet 39
  40. 40. 次のテストを追加する 例)3の倍数の場合、”Fizz”を返す 追加したテストのみ失敗することを確認 #ngtnet 40
  41. 41. 明白な実装 実装が自明であれば 仮実装をスキップしてもよい ギアを上げるイメージ 例)引数と3との剰余が0なら”Fizz”を返す #ngtnet 41
  42. 42. 以後同様に続ける 続きはデモで #ngtnet 42
  43. 43. TDDの指針 #ngtnet 43
  44. 44. いつTDDを行うか 不安を感じたとき ライブラリの使い方に自信がない サードパーティの実装が信用出来ない など 使い捨てのコードでないとき 繰り返し実行しないテストはただのコスト #ngtnet 44
  45. 45. いつTDDを行うか GUIでないとき GUIのテストコストは非常に高い GUIの変更は頻繁にある トライ&エラーであれこれしないとき 確定後のコードにテストを書いてもよい ≒テストファーストにこだわらない #ngtnet 45
  46. 46. どんなテストが良いテスト?  F.I.R.S.T  Fast 高速  Independent 独立している  Repeatable 繰り返し実行可能  Self-Validating 手動での検証がない  Timely テストファースト #ngtnet 46
  47. 47. どのようにテストを行うか 各種テスト技法を参考に 同値クラス 境界値分析 デシジョンテーブル etc #ngtnet 47
  48. 48. 既存コードがある場合 テストのないコードはレガシーコードだ! #ngtnet 48 レガシーコード 改善ガイド (マイケル・C・フェザーズ著、 翔泳社刊) http://www.shoeisha.co.jp/book/detail/9784798116839
  49. 49. 最後に #ngtnet 49
  50. 50. 最後に TDDはセンスではなくスキル 訓練次第で誰でも習得可能 自分1人でも始められる 安心を得て健康になろう #ngtnet 50

×