First Step TDD

657 views

Published on

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

  • Be the first to like this

No Downloads
Views
Total views
657
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • First Step TDD

    1. 1. First Step TDD2012/7/27 yoyogi.rb
    2. 2. TDDと開発環境
    3. 3. 自己紹介curl http://cui-about.me/nysalor今回あまり準備していません(ごめんなさい)
    4. 4. TDD?テスト駆動開発テストを書いてからコードを書く
    5. 5. 手順
    6. 6. 手順 Red 失敗するテストを書く
    7. 7. 手順 Red 失敗するテストを書く Green 成功するコードを書く
    8. 8. 手順 Red 失敗するテストを書く Green 成功するコードを書く Refactor リファクタリング
    9. 9. Why TDD?常に整合性を保ってプログラミングできるいつでもリファクタリングできる要件や仕様の不明点がはっきりする自信と安心を与えてくれる(重要)
    10. 10. RspecテスティングフレームワークRailsでよく使われるが、Ruby全般で利用可能視覚的に分かりやすい
    11. 11. インストールgem install rspec
    12. 12. 何を作るか?誕生日と現在の日付から年齢を計算するクラスAgeCalc
    13. 13. とりあえず書いてみる
    14. 14. とりあえず書いてみる[age_calc_spec.rb]require ./age_calc
    15. 15. とりあえず書いてみる[age_calc_spec.rb]require ./age_calc[age_calc.rb]class AgeCalcend
    16. 16. とりあえず書いてみる テストコード[age_calc_spec.rb]require ./age_calc[age_calc.rb]class AgeCalcend
    17. 17. とりあえず書いてみる テストコード[age_calc_spec.rb]require ./age_calc プロダクトコード[age_calc.rb]class AgeCalcend
    18. 18. テスト実行
    19. 19. テスト実行% rspec -cfs --color age_calc_spec.rbNo examples found.Finished in 0.00005 seconds0 examples, 0 failures
    20. 20. 事前準備
    21. 21. 事前準備[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do before do @age_calc = AgeCalc.new endend
    22. 22. 事前準備 テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do before do @age_calc = AgeCalc.new endend
    23. 23. 最初のテスト
    24. 24. 最初のテスト[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do before do @age_calc = AgeCalc.new end it "birthdayで誕生日が設定できること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.birthday.should == Date.new(1989,2,25) endend
    25. 25. 最初のテスト テストコード[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do before do @age_calc = AgeCalc.new end it "birthdayで誕生日が設定できること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.birthday.should == Date.new(1989,2,25) endend
    26. 26. Red!
    27. 27. Red!% rspec -cfs --color age_calc_spec.rbAgeCalc birthdayで誕生日が設定できること (FAILED - 1)Failures: 1) AgeCalc birthdayで誕生日が設定できること Failure/Error: @age_calc.birthday = Date.new(1989,2,25) NoMethodError: undefined method `birthday= for #<AgeCalc:0x007f8c02832e40> # ./age_calc_spec.rb:11:in `block (2 levels) in <top(required)>Finished in 0.00045 seconds1 example, 1 failureFailed examples:rspec ./age_calc_spec.rb:10 # AgeCalc birthdayで誕生日が設定できること
    28. 28. 実装
    29. 29. 実装#[age_calc.rb]class AgeCalc def birthday=(date) @birthday = date end def birthday @birthday endend
    30. 30. 実装 プロダクトコード#[age_calc.rb]class AgeCalc def birthday=(date) @birthday = date end def birthday @birthday endend
    31. 31. Green!
    32. 32. Green!% rspec -cfs --color age_calc_spec.rbAgeCalc birthdayで誕生日が設定できることFinished in 0.00037 seconds1 example, 0 failures
    33. 33. リファクタリング
    34. 34. リファクタリング#[age_calc.rb]class AgeCalc attr_accessor :birthdayend
    35. 35. リファクタリング プロダクトコード#[age_calc.rb]class AgeCalc attr_accessor :birthdayend
    36. 36. Green!
    37. 37. Green!% rspec -cfs --color age_calc_spec.rbAgeCalc birthdayで誕生日が設定できることFinished in 0.00037 seconds1 example, 0 failures
    38. 38. テストケース追加
    39. 39. テストケース追加[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do ... it "ageで年齢が返ること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should == 23 endend
    40. 40. テストケース追加 テストコード[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do ... it "ageで年齢が返ること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should == 23 endend
    41. 41. Red!
    42. 42. Red!% rspec -cfs --color age_calc_spec.rbAgeCalc birthdayで誕生日が設定できること (FAILED - 1)Failures: 1) AgeCalc ageで年齢が返ること Failure/Error: @age_calc.age.should == 23 NoMethodError: undefined method `age for #<AgeCalc:0x007fb8d28279d0> # ./age_calc_spec.rb:17:in `block (2 levels) in <top(required)>Finished in 0.00045 seconds2 example, 1 failureFailed examples:rspec ./age_calc_spec.rb:15 # AgeCalc ageで年齢が返ること
    43. 43. 実装
    44. 44. 実装#[age_calc.rb]class AgeCalc attr_accessor :birthday def age (Time.now.strftime("%Y%m%d").to_i - @birthday.strftime("%Y%m%d").to_i) / 10000 endend
    45. 45. 実装 プロダクトコード#[age_calc.rb]class AgeCalc attr_accessor :birthday def age (Time.now.strftime("%Y%m%d").to_i - @birthday.strftime("%Y%m%d").to_i) / 10000 endend
    46. 46. Green!
    47. 47. Green!% rspec -cfs --color age_calc_spec.rb#=> 省略
    48. 48. テストケース追加
    49. 49. テストケース追加#[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do ... it "birthdayが未設定の場合、ageでnilが返ること" do pending “あとで書く” @age_calc.age.should be_nil endend
    50. 50. テストケース追加 テストコード#[age_calc_spec.rb]require ./age_calcrequire datedescribe AgeCalc do ... it "birthdayが未設定の場合、ageでnilが返ること" do pending “あとで書く” @age_calc.age.should be_nil endend
    51. 51. Red!
    52. 52. Red!% rspec -cfs --color age_calc_spec.rb#=> 省略
    53. 53. 実装
    54. 54. 実装[age_calc.rb]class AgeCalc... def age if @birthday (Time.now.strftime("%Y%m%d").to_i - @birthday.strftime("%Y%m%d").to_i) / 10000 else nil end endend
    55. 55. 実装 プロダクトコード[age_calc.rb]class AgeCalc... def age if @birthday (Time.now.strftime("%Y%m%d").to_i - @birthday.strftime("%Y%m%d").to_i) / 10000 else nil end endend
    56. 56. Green!
    57. 57. Green!% rspec -cfs --color age_calc_spec.rb#=> 省略
    58. 58. その他のMatcher
    59. 59. raise_error
    60. 60. raise_error[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "birthdayにDate以外の値を設定すると、ageで例外が返ること" do @age_calc.birthday = “23 years ago” lambda{@age_calc.age}.should raise_error endend
    61. 61. raise_error テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "birthdayにDate以外の値を設定すると、ageで例外が返ること" do @age_calc.birthday = “23 years ago” lambda{@age_calc.age}.should raise_error endend
    62. 62. change
    63. 63. change[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "increment_ageでageが1増えること" do @age_calc.birthday = Date.new(1989,2,25) lambda {@age_calc.increment_age}.shouldchange(@age_calc.age).from(23).to(24) endend
    64. 64. change テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "increment_ageでageが1増えること" do @age_calc.birthday = Date.new(1989,2,25) lambda {@age_calc.increment_age}.shouldchange(@age_calc.age).from(23).to(24) endend
    65. 65. be_close
    66. 66. be_close[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "ageが20から30の間にあること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should be_close(20,30) endend
    67. 67. be_close テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "ageが20から30の間にあること" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should be_close(20,30) endend
    68. 68. be_xxxx
    69. 69. be_xxxx[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "yearsが空になること" do @age_calc.years.should be_empty endend
    70. 70. be_xxxx テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "yearsが空になること" do @age_calc.years.should be_empty endend
    71. 71. 否定
    72. 72. 否定[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "ageがDateクラスのオブジェクトでないこと" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should_not be_is_a(Date) endend
    73. 73. 否定 テストコード[age_calc_spec.rb]require ./age_calcdescribe AgeCalc do ... it "ageがDateクラスのオブジェクトでないこと" do @age_calc.birthday = Date.new(1989,2,25) @age_calc.age.should_not be_is_a(Date) endend
    74. 74. 以下余談(時間があれば)
    75. 75. 開発環境
    76. 76. rvm/rbenv
    77. 77. rvm/rbenvRVM http://beginrescueend.com/
    78. 78. rvm/rbenvRVM http://beginrescueend.com/rbenv https://github.com/sstephenson/rbenv
    79. 79. rvm/rbenvRVM http://beginrescueend.com/rbenv https://github.com/sstephenson/rbenv 複数バージョンのRubyを同居 「前のバージョン用のgemを使ってしまった」を防ぐ 開発・運用環境で同じRubyを使うメリット
    80. 80. rvm/rbenvRVM http://beginrescueend.com/rbenv https://github.com/sstephenson/rbenv
    81. 81. rvm/rbenvRVM http://beginrescueend.com/rbenv https://github.com/sstephenson/rbenv
    82. 82. rvm/rbenvRVM http://beginrescueend.com/rbenv https://github.com/sstephenson/rbenv RVMが主流→最近はrbenvが流行 RVMは多機能だけど何度かやらかした rbenvは実行ファイルにやや癖がある?
    83. 83. screen/tmux
    84. 84. screen/tmux
    85. 85. screen/tmux
    86. 86. screen/tmux
    87. 87. screen/tmuxターミナルマルチプレクサirb,logなど複数のシェルを行き来するのに便利落ちても再起動するまでセッションが消えない設定がけっこう大変tmuxinator/screeninator
    88. 88. git
    89. 89. git 分散リポジトリ 学習コストが高い? svnに慣れすぎていなければ平気 githubやherokuでどっちみち必要 GUIクライアント?
    90. 90. sourcetree
    91. 91. sourcetreehttp://www.sourcetreeapp.com/
    92. 92. sourcetreehttp://www.sourcetreeapp.com/
    93. 93. sourcetreehttp://www.sourcetreeapp.com/ 見やすい 多機能(っぽいけどあまり使ってない) 登録必要だけど無料
    94. 94. gitx
    95. 95. gitx http://gitx.frim.nl/
    96. 96. gitx http://gitx.frim.nl/
    97. 97. gitx http://gitx.frim.nl/ 軽い 機能少ない diff見るだけなら十分
    98. 98. github
    99. 99. github http://github.com/
    100. 100. github http://github.com/
    101. 101. github http://github.com/ githubでいいんじゃね? プライベートリポジトリは有料 ネットがないと使えない
    102. 102. tig
    103. 103. tig https://github.com/jonas/tig
    104. 104. tig https://github.com/jonas/tig 意外に見やすい おすすめ
    105. 105. やっぱりCUI
    106. 106. やっぱりCUIGUIはdiff見たり検索するだけどっちみちCUIの操作は必要苦手な人は覚えましょうgit log --graph
    107. 107. Emacs
    108. 108. EmacsCocoa Emacs(自分でビルド)inline-patchfull screen
    109. 109. Emacs
    110. 110. Emacsruby-moderuby-electricrinarietagsauto-complete
    111. 111. Emacs
    112. 112. Emacs
    113. 113. Emacs
    114. 114. Emacs
    115. 115. Emacs設定をDropboxに置く起動したらずっとそのままexport EDITOR=emacsclient
    116. 116. Pow
    117. 117. Pow http://pow.cx/
    118. 118. Pow http://pow.cx/
    119. 119. Pow http://pow.cx/
    120. 120. Pow http://pow.cx/
    121. 121. Pow http://pow.cx/いちいちrails serverしなくてもいいhttp://xxxx.devでアクセスできる複数プロジェクトの同時開発に対応最近LAN内の別の端末から見れるようになった
    122. 122. Pow http://pow.cx/
    123. 123. Pow http://pow.cx/
    124. 124. Pow http://pow.cx/gem install powderpowder -rでサーバ再起動powder applog,powder linkなど
    125. 125. guard
    126. 126. guardhttps://github.com/guard/guard
    127. 127. guardhttps://github.com/guard/guardTDDファイルが更新されると自動実行いちいちrspecを実行するとサボりがちcoffee scriptの開発などにも使えるautospecというのもある
    128. 128. spork
    129. 129. sporkhttps://github.com/sporkrb/spork
    130. 130. sporkhttps://github.com/sporkrb/spork分散テスト同時に複数のテストが実行されるデータベースを初期化する仕組みが不可欠
    131. 131. 質疑応答
    132. 132. 質疑応答if available?  Question.all.map(&:answer!)end
    133. 133. gist https://gist.github.com/ 3187454 (test) https://gist.github.com/ 3187465 (production)

    ×