テスト駆動開発入門

3,429 views

Published on

2011年1月29日の第4回minami.rb勉強会で行った講義の資料です。

テスト駆動開発入門

  1. 1. テスト駆動開発入門 yalab
  2. 2. テスト駆動って何?
  3. 3. そんなことはどうでもいい
  4. 4. テスト駆動って何がいいの?
  5. 5. テスト駆動って何がいいの? バグが減る ライブラリが作れるようになる
  6. 6. テスト駆動開発ってどうやるの?
  7. 7. いきなり演習
  8. 8. そうだ。ブログのサイドバーにカレンダーを付けよう
  9. 9. カレンダーって使いまわしできそうだからライブラリにしておくか。
  10. 10. ということでカレンダーを作ります。
  11. 11. さて、とりあえずテストを書くか
  12. 12. # calendar_test.rbrequire test/unitrequire daterequire ./calendarclass CalendarTest < Test::Unit::TestCase def test_jan_first_day jan = Calendar.new(2011, 1) assert_equal Date.new(2011, 1, 1), jan.first_day endend
  13. 13. よし、テストするぞ。
  14. 14. $ ruby calendar_test.rb<internal:lib/rubygems/custom_require>:29:in `require: nosuch file to load -- ./calendar (LoadError) from <internal:lib/rubygems/custom_require>:29:in`require from calendar_test.rb:3:in `<main>
  15. 15. アハハ、ファイルが無いってさ。そりゃテスト以前の問題だよね。
  16. 16. $ touch calendar.rb$ ruby calendar_test.rbLoaded suite calendar_testStartedEFinished in 0.000419 seconds. 1) Error:test_jan_first_day(CalendarTest):NameError: uninitialized constant CalendarTest::Calendar calendar_test.rb:7:in `test_jan_first_day1 tests, 0 assertions, 0 failures, 1 errors, 0 skipsTest run options: --seed 51538
  17. 17. わかってるさ。空ファイルだからね。クラスとメソッドぐらい書かないとね。
  18. 18. # calendar.rbclass Calendar def initialize(year, month) end def first_day endend
  19. 19. $ ruby calendar_test.rbLoaded suite calendar_testStartedFFinished in 0.000644 seconds. 1) Failure:test_jan_first_day(CalendarTest) [calendar_test.rb:8]:<#<Date: 2011-01-01 (4911125/2,0,2299161)>> expected butwas<nil>.1 tests, 1 assertions, 1 failures, 0 errors, 0 skipsTest run options: --seed 39704
  20. 20. よ~し。とりあえずエラーはなくなった。次はfailureを無くすか。
  21. 21. # calendar.rbclass Calendar def initialize(year, month) end def first_day Date.new(2011, 1, 1) endend
  22. 22. $ ruby calendar_test.rbLoaded suite calendar_testStarted.Finished in 0.000355 seconds.1 tests, 1 assertions, 0 failures, 0 errors, 0 skipsTest run options: --seed 57673
  23. 23. Cool! テストに通ったぜ!
  24. 24. お、何だい?Calendarを作ってるのか?どれどれ...
  25. 25. ん~、これはイマイチだな。first_dayを呼ぶたびにDateのインスタンスを作ってるじゃないか。
  26. 26. initializeの時に一回だけ作るようにしたらどうだい?
  27. 27. このコードだといくつもDateのインスタンスを作っちゃうな。じゃあリファクタリングするか。
  28. 28. # calendar.rbclass Calendar def initialize(year, month) @first_day = Date.new(2011, 1, 1) end def first_day @first_day endend
  29. 29. 変更を加えたならテストしておけよ。
  30. 30. $ ruby calendar_test.rbLoaded suite calendar_testStarted.Finished in 0.000343 seconds.1 tests, 1 assertions, 0 failures, 0 errors, 0 skipsTest run options: --seed 19307
  31. 31. よし。テストも通ってる。
  32. 32. うん。なかなかいいな。ただ僕がやるならそこはattr_readerを使ったほうがコードが短くなっていいと思うな。
  33. 33. first_dayメソッドってやってることはgetterだからattr_readerで書けるか。
  34. 34. # calendar.rbclass Calendar attr_reader :first_day def initialize(year, month) @first_day = Date.new(2011, 1, 1) endend
  35. 35. コードを書き換えたらテストをしとけよ
  36. 36. よし、リファクタリングしたしテストをしとかないと。
  37. 37. $ ruby calendar_test.rbLoaded suite calendar_testStarted.Finished in 0.000375 seconds.1 tests, 1 assertions, 0 failures, 0 errors, 0 skipsTest run options: --seed 61238
  38. 38. よし、コードは書き換えたけど同じ動きをしてる。
  39. 39. 演習 月末を返す last_day メソッドを作ってください。 第一週の日曜日(2011年1月のカレンダーなら2010年12 月26日)を返すメソッドを作ってください。 最終週の土曜日(21011年1月のカレンダーなら2011年2 月5日)を返すメソッドを作ってください。 各週と各日を操作するeach_weekとeach_dayを作ってく ださい。 月曜始まりと日曜始まりの両方を使えるようにしてく ださい。
  40. 40. アップロード用追記 今回作成したライブラリには calendar.rb 内で require date をしていないという致命的な不具 合を「意図的に」残しました。 テストが通ったらからバグが無いとは限らない という例とするためです。
  41. 41. アップロード用追記 しかしながらテストが通ってるうちはテストの 範囲内では少なくとも正常に動作するという保 証になります。
  42. 42. テスト重要
  43. 43. 資料 テスト駆動開発入門 http://www.amazon.co.jp/dp/4894717115 Ruby/Rails勉強会@関西­20 初級者向けレッスン資料 http://bit.ly/dKk220

×