Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

テスト駆動開発入門

3,496 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

×