SlideShare uma empresa Scribd logo
1 de 133
First Step TDD
2012/7/27 yoyogi.rb
TDDと開発環境
自己紹介


curl http://cui-about.me/nysalor
今回あまり準備していません(ごめんなさい)
TDD?


テスト駆動開発

テストを書いてからコードを書く
手順
手順
 Red   失敗するテストを書く
手順
 Red     失敗するテストを書く

 Green   成功するコードを書く
手順
   Red      失敗するテストを書く

  Green     成功するコードを書く

 Refactor    リファクタリング
Why TDD?

常に整合性を保ってプログラミングできる

いつでもリファクタリングできる

要件や仕様の不明点がはっきりする

自信と安心を与えてくれる(重要)
Rspec


テスティングフレームワーク

Railsでよく使われるが、Ruby全般で利用可能

視覚的に分かりやすい
インストール



gem install rspec
何を作るか?


誕生日と現在の日付から年齢を計算するクラス

AgeCalc
とりあえず書いてみる
とりあえず書いてみる

[age_calc_spec.rb]
require './age_calc'
とりあえず書いてみる

[age_calc_spec.rb]
require './age_calc'




[age_calc.rb]
class AgeCalc
end
とりあえず書いてみる
                       テストコード


[age_calc_spec.rb]
require './age_calc'




[age_calc.rb]
class AgeCalc
end
とりあえず書いてみる
                       テストコード


[age_calc_spec.rb]
require './age_calc'



                       プロダクトコード

[age_calc.rb]
class AgeCalc
end
テスト実行
テスト実行
% rspec -cfs --color age_calc_spec.rb
No examples found.

Finished in 0.00005 seconds
0 examples, 0 failures
事前準備
事前準備

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  before do
    @age_calc = AgeCalc.new
  end
end
事前準備
                              テストコード



[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  before do
    @age_calc = AgeCalc.new
  end
end
最初のテスト
最初のテスト
[age_calc_spec.rb]
require './age_calc'
require 'date'
describe 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)
  end
end
最初のテスト
                                            テストコード
[age_calc_spec.rb]
require './age_calc'
require 'date'
describe 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)
  end
end
Red!
Red!
% rspec -cfs --color age_calc_spec.rb
AgeCalc
  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 seconds
1 example, 1 failure

Failed examples:

rspec ./age_calc_spec.rb:10 # AgeCalc birthdayで誕生日が設定できる
こと
実装
実装

#[age_calc.rb]
class AgeCalc
  def birthday=(date)
    @birthday = date
  end

  def birthday
    @birthday
  end
end
実装
                        プロダクトコード


#[age_calc.rb]
class AgeCalc
  def birthday=(date)
    @birthday = date
  end

  def birthday
    @birthday
  end
end
Green!
Green!


% rspec -cfs --color age_calc_spec.rb
AgeCalc
  birthdayで誕生日が設定できること

Finished in 0.00037 seconds
1 example, 0 failures
リファクタリング
リファクタリング


#[age_calc.rb]
class AgeCalc
  attr_accessor :birthday
end
リファクタリング
                            プロダクトコード




#[age_calc.rb]
class AgeCalc
  attr_accessor :birthday
end
Green!
Green!


% rspec -cfs --color age_calc_spec.rb
AgeCalc
  birthdayで誕生日が設定できること

Finished in 0.00037 seconds
1 example, 0 failures
テストケース追加
テストケース追加

[age_calc_spec.rb]
require './age_calc'
require 'date'
describe AgeCalc do
  ...
  it "ageで年齢が返ること" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should == 23
  end
end
テストケース追加
                                               テストコード

[age_calc_spec.rb]
require './age_calc'
require 'date'
describe AgeCalc do
  ...
  it "ageで年齢が返ること" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should == 23
  end
end
Red!
Red!
% rspec -cfs --color age_calc_spec.rb
AgeCalc
  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 seconds
2 example, 1 failure

Failed examples:

rspec ./age_calc_spec.rb:15 # AgeCalc ageで年齢が返ること
実装
実装

#[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
  end
end
実装
                                         プロダクトコード



#[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
  end
end
Green!
Green!



% rspec -cfs --color age_calc_spec.rb
#=> 省略
テストケース追加
テストケース追加
#[age_calc_spec.rb]
require './age_calc'
require 'date'
describe AgeCalc do

  ...
  it "birthdayが未設定の場合、ageでnilが返ること" do
    pending “あとで書く”
    @age_calc.age.should be_nil
  end
end
テストケース追加
                                   テストコード
#[age_calc_spec.rb]
require './age_calc'
require 'date'
describe AgeCalc do

  ...
  it "birthdayが未設定の場合、ageでnilが返ること" do
    pending “あとで書く”
    @age_calc.age.should be_nil
  end
end
Red!
Red!



% rspec -cfs --color age_calc_spec.rb
#=> 省略
実装
実装
[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
  end
end
実装
                                         プロダクトコード
[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
  end
end
Green!
Green!



% rspec -cfs --color age_calc_spec.rb
#=> 省略
その他のMatcher
raise_error
raise_error

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "birthdayにDate以外の値を設定すると、ageで例外が返る
こと" do
    @age_calc.birthday = “23 years ago”
    lambda{@age_calc.age}.should raise_error
  end
end
raise_error
                                               テストコード

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "birthdayにDate以外の値を設定すると、ageで例外が返る
こと" do
    @age_calc.birthday = “23 years ago”
    lambda{@age_calc.age}.should raise_error
  end
end
change
change

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "increment_ageでageが1増えること" do
    @age_calc.birthday = Date.new(1989,2,25)
    lambda {@age_calc.increment_age}.should
change(@age_calc.age).from(23).to(24)
  end
end
change
                                               テストコード

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "increment_ageでageが1増えること" do
    @age_calc.birthday = Date.new(1989,2,25)
    lambda {@age_calc.increment_age}.should
change(@age_calc.age).from(23).to(24)
  end
end
be_close
be_close

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "ageが20から30の間にあること" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should be_close(20,30)
  end
end
be_close
                                               テストコード


[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "ageが20から30の間にあること" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should be_close(20,30)
  end
end
be_xxxx
be_xxxx

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "yearsが空になること" do
    @age_calc.years.should be_empty
  end
end
be_xxxx
                                      テストコード


[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "yearsが空になること" do
    @age_calc.years.should be_empty
  end
end
否定
否定

[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "ageがDateクラスのオブジェクトでないこと" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should_not be_is_a(Date)
  end
end
否定
                                               テストコード


[age_calc_spec.rb]
require './age_calc'
describe AgeCalc do
  ...
  it "ageがDateクラスのオブジェクトでないこと" do
    @age_calc.birthday = Date.new(1989,2,25)
    @age_calc.age.should_not be_is_a(Date)
  end
end
以下余談(時間があれば)
開発環境
rvm/rbenv
rvm/rbenv
RVM http://beginrescueend.com/
rvm/rbenv
RVM http://beginrescueend.com/

rbenv https://github.com/sstephenson/rbenv
rvm/rbenv
RVM http://beginrescueend.com/

rbenv https://github.com/sstephenson/rbenv

 複数バージョンのRubyを同居

 「前のバージョン用のgemを使ってしまった」を防ぐ

 開発・運用環境で同じRubyを使うメリット
rvm/rbenv
RVM http://beginrescueend.com/

rbenv https://github.com/sstephenson/rbenv
rvm/rbenv
RVM http://beginrescueend.com/

rbenv https://github.com/sstephenson/rbenv
rvm/rbenv
RVM http://beginrescueend.com/

rbenv https://github.com/sstephenson/rbenv

 RVMが主流→最近はrbenvが流行

 RVMは多機能だけど何度かやらかした

 rbenvは実行ファイルにやや癖がある?
screen/tmux
screen/tmux
screen/tmux
screen/tmux
screen/tmux
ターミナルマルチプレクサ

irb,logなど複数のシェルを行き来するのに便利

落ちても再起動するまでセッションが消えない

設定がけっこう大変

tmuxinator/screeninator
git
git
 分散リポジトリ

 学習コストが高い?

 svnに慣れすぎていなければ平気

 githubやherokuでどっちみち必要

 GUIクライアント?
sourcetree
sourcetree
http://www.sourcetreeapp.com/
sourcetree
http://www.sourcetreeapp.com/
sourcetree
http://www.sourcetreeapp.com/




                          見やすい
                          多機能(っぽいけどあまり使ってない)
                          登録必要だけど無料
gitx
gitx
       http://gitx.frim.nl/
gitx
       http://gitx.frim.nl/
gitx
       http://gitx.frim.nl/




                              軽い
                              機能少ない
                              diff見るだけなら十分
github
github
   http://github.com/
github
   http://github.com/
github
   http://github.com/




                        githubでいいんじゃね?
                        プライベートリポジトリは有料
                        ネットがないと使えない
tig
tig
  https://github.com/jonas/tig
tig
  https://github.com/jonas/tig




                             意外に見やすい
                             おすすめ
やっぱりCUI
やっぱりCUI

GUIはdiff見たり検索するだけ

どっちみちCUIの操作は必要

苦手な人は覚えましょう

git log --graph
Emacs
Emacs


Cocoa Emacs(自分でビルド)

inline-patch
full screen
Emacs
Emacs

ruby-mode
ruby-electric
rinari
etags
auto-complete
Emacs
Emacs
Emacs
Emacs
Emacs


設定をDropboxに置く

起動したらずっとそのまま

export EDITOR=emacsclient
Pow
Pow
      http://pow.cx/
Pow
      http://pow.cx/
Pow
      http://pow.cx/
Pow
      http://pow.cx/
Pow
      http://pow.cx/

いちいちrails serverしなくてもいい

http://xxxx.devでアクセスできる

複数プロジェクトの同時開発に対応

最近LAN内の別の端末から見れるようになった
Pow
      http://pow.cx/
Pow
      http://pow.cx/
Pow
        http://pow.cx/


gem install powder
powder -rでサーバ再起動

powder applog,powder linkなど
guard
guard
https://github.com/guard/guard
guard
https://github.com/guard/guard

TDD
ファイルが更新されると自動実行

いちいちrspecを実行するとサボりがち

coffee scriptの開発などにも使える

autospecというのもある
spork
spork
https://github.com/sporkrb/spork
spork
https://github.com/sporkrb/spork



分散テスト

同時に複数のテストが実行される

データベースを初期化する仕組みが不可欠
質疑応答
質疑応答

if available?
  Question.all.map(&:answer!)
end
gist

 https://gist.github.com/
 3187454 (test)
 https://gist.github.com/
 3187465 (production)

Mais conteúdo relacionado

Semelhante a First Step TDD

[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
Insight Technology, Inc.
 
USP 友の会 LT 資料 20130413
USP 友の会 LT 資料 20130413USP 友の会 LT 資料 20130413
USP 友の会 LT 資料 20130413
博文 斉藤
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
papamitra
 
Functional Testing in #YAPCASIA
Functional Testing in #YAPCASIAFunctional Testing in #YAPCASIA
Functional Testing in #YAPCASIA
kyon mm
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
higaki
 

Semelhante a First Step TDD (20)

Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koa
 
VerilatorとSystemC
VerilatorとSystemCVerilatorとSystemC
VerilatorとSystemC
 
JJUG CCC 2016 fall バイトコードが君のトモダチになりたがっている
JJUG CCC 2016 fall バイトコードが君のトモダチになりたがっているJJUG CCC 2016 fall バイトコードが君のトモダチになりたがっている
JJUG CCC 2016 fall バイトコードが君のトモダチになりたがっている
 
Java 9で進化する診断ツール
Java 9で進化する診断ツールJava 9で進化する診断ツール
Java 9で進化する診断ツール
 
[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
[A33] [特濃jpoug statspack on pdb oracle database 12c] 20131115 補足・続報付き
 
ScalaCL in ScalaKaigi
ScalaCL in ScalaKaigiScalaCL in ScalaKaigi
ScalaCL in ScalaKaigi
 
USP 友の会 LT 資料 20130413
USP 友の会 LT 資料 20130413USP 友の会 LT 資料 20130413
USP 友の会 LT 資料 20130413
 
Babelfish Compatibility
Babelfish CompatibilityBabelfish Compatibility
Babelfish Compatibility
 
Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話
 
about dakota6.7 gui
about dakota6.7 guiabout dakota6.7 gui
about dakota6.7 gui
 
Scalaで始める競技プログラミング
Scalaで始める競技プログラミングScalaで始める競技プログラミング
Scalaで始める競技プログラミング
 
20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
Scala × DDD × 弊社実践例
Scala × DDD × 弊社実践例Scala × DDD × 弊社実践例
Scala × DDD × 弊社実践例
 
Functional Testing in #YAPCASIA
Functional Testing in #YAPCASIAFunctional Testing in #YAPCASIA
Functional Testing in #YAPCASIA
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
 
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech
歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
 

Último

The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
koheioishi1
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
YukiTerazawa
 

Último (8)

生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
 
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
 
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
 
The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
 
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
 
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
 
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
 

First Step TDD

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n