rspec と cucumber

64
RSpec と Cucumber Powered by Rabbit 0.9.2 RSpec と Cucumber とみたまさひろ 2011-01-15

Upload: masahiro-tomita

Post on 05-Dec-2014

9.967 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RSpec と Cucumber

とみたまさひろ2011-01-15

Page 2: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

自己紹介

とみた まさひろ✓

プログラマー✓

mailto:[email protected]

http://d.hatena.ne.jp/tmtms✓

http://twitter.com/tmtms✓

1/63

Page 3: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

自己紹介

日本Rubyの会✓

日本MySQLユーザ会✓

Ruby/MySQL ライブラリ✓

Ruby歴, MySQL歴 十数年✓

2/63

Page 4: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

自己紹介

こんな本書きました

3/63

Page 5: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

NSEG

#1 Rubyの黒魔術✓

#3 はじめてのRuby拡張ライブラリ

#6 Ruby紹介✓

4/63

Page 6: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

今回は RSpec と

Cucumber の話

5/63

Page 7: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

読みやすくて自動実行できるテスト

6/63

Page 8: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RSpec7/63

Page 9: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RSpec

Rubyプログラム用の TDDツール✓

最新バージョン 2.4✓

http://relishapp.com/rspec✓

8/63

Page 10: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RSpec

9/63

Page 11: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

「The RSpec Book」

10/63

Page 12: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

特徴

英語っぽい✓

モックが強力&簡単✓

ファイル変更時に自動的実行✓

テストカバー率が測れる✓

11/63

Page 13: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

インストール

% sudo gem install rspec

12/63

Page 14: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

基本的な書き方

ファイル名は *_spec.rb✓

○○について --- describe✓

○○の場合 --- context✓

○○となること --- it✓

13/63

Page 15: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

基本的な書き方

describe Array do context 'when new' do it 'should be empty' do Array.new.should be_empty end it 'size should == 0' do Array.new.size.should == 0 end endend

14/63

Page 16: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

実行

% rspec array_spec.rb..

Finished in 0.00054 seconds2 examples, 0 failures

15/63

Page 17: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

ドキュメントっぽい出力

% rspec -fd array_spec.rb

Array when new should be empty size should == 0

Finished in 0.00068 seconds2 examples, 0 failures

16/63

Page 18: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

冗長

describe Array do context 'when new' do it 'should be empty' do Array.new.should be_empty end it 'size should == 0' do Array.new.size.should == 0 end endend

17/63

Page 19: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

簡潔に

describe Array do context 'when new' do it{should be_empty} its(:size){should == 0} endend

18/63

Page 20: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

出力

% rspec -fd b.rb

Array when new should be empty size should == 0

Finished in 0.00078 seconds2 examples, 0 failures

19/63

Page 21: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

subject

describe Array do context 'when new with 3' do subject{Array.new(3)} it{should == [nil, nil, nil]} its(:size){should == 3} endend

20/63

Page 22: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

before & after

describe Hoge do before do # 前処理 @hoge = Hoge.new end after do # 後処理 @hoge.close end it '...' do @hoge.fuga.should == 123 endend

21/63

Page 23: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

should

==, =~, >, >=, <, <=✓

be_xxx : obj.xxx? メソッドが真✓

be_true, be_false, be_nil✓

[1,2,3].should have(3).items✓

[1,2,3].should include(2)✓

22/63

Page 24: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

例外処理

expect{...}.to raise_error(RuntimeError, 'msg...')

23/63

Page 25: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

英語っぽいっていってもやりすぎだろJK

ary = []expect{ary.push 123}.to change{ary.size}.from(0).to(1)

24/63

Page 26: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モック25/63

Page 27: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モック

ダミーのオブジェクト✓

ファイル, ネットワーク, DB, 時刻, etc...

double() でモックオブジェクトを作成

26/63

Page 28: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モック

obj = double 'label', :size=>3obj.size #=> 3obj.hoge #=> Error

27/63

Page 29: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モック

obj = double 'Array'obj.stub(:size).and_return 3obj.stub(:values_at).with(0).and_return 'a'

# 呼ばれなかったらエラーobj.should_receive(:fetch)

28/63

Page 30: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モック

# 一度だけ呼び出されるobj.should_receive(:hoge).once

# n回以上呼び出されるobj.should_receive(:hoge).at_least(n).times

# 引数が正規表現に一致するobj.should_receive(:hoge).with(/.../)

# 引数が文字列obj.should_receive(:hoge).with(an_instance_of(String))

# 引数が :key=>val を含むハッシュobj.should_receive(:hoge).with(hash_including(:key=>val))

29/63

Page 31: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

既存オブジェクトのメソッドを置き換え可能

it の中だけで有効

# 特定の時刻で実行したいテストbefore do t = Time.local(2011,1,15,18,30,0) Time.stub(:now).and_return tendits(:tmpfile){should == '20110115183000.tmp'}

30/63

Page 32: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

モックを返す

before do # どんなメソッド呼び出しもエラーにしない logger = double('Logger').as_null_object Logger.stub(:new).and_return loggerendit ...

31/63

Page 33: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

自動実行

32/63

Page 34: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

autotest

.rspeclib/hoge.rbspec/hoge_spec.rb

hoge.rb が変更されると自動的にhoge_spec.rb が実行される

33/63

Page 35: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

インストール&実行

% sudo gem install ZenTest

% autotest

34/63

Page 36: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

デモ35/63

Page 37: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

カバレッジ

テストカバー率を測れる✓

Ruby 1.9 ではまだちゃんと動作しない(?)

36/63

Page 38: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RCov

37/63

Page 39: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

インストール&実行

% sudo gem install rcov

% rcov rspec spec/hoge_spec.rb

テスト対象のものだけ集計% rcov -x ^/ -x _spec.rb rspec spec/hoge_spec.rb

38/63

Page 40: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

デモ39/63

Page 41: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

RSpec の話はここま

で40/63

Page 42: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

Cucumber

41/63

Page 43: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

Cucumber

受け入れテスト用ツール✓

プログラムを外部からテスト✓

テスト対象の言語は問わない✓

テスト自体は Ruby で記述✓

http://cukes.info/✓

42/63

Page 44: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

Cucumber

43/63

Page 45: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

「はじめる! Cucumber」

達人出版会の電子書籍。Railsプログラムのテスト44/63

Page 46: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

インストール

% sudo gem install cucumber

45/63

Page 47: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

書き方

# language: jaフィーチャ: ○○できる ○○として、 ○○したい。 なぜなら、○○だから。

シナリオ: ○○すると○○される 前提 ○○の状態 もし ○○する かつ ○○する ならば ○○されること

46/63

Page 48: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

文章で書ける

プログラマじゃなくても読める✓

プログラマじゃなくても書ける…かは微妙

47/63

Page 49: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

こんな場面で

Web アプリケーションのテスト✓

Rails で使うと便利な機能多数✓

Rails や Web アプリ以外でも使える

48/63

Page 50: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

今回の例は

SMTPの送信テスト✓

プログラム開発以外にも使えるよ!

Rails 以外にも使えるよ!というか Rails 知らないし

49/63

Page 51: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

feature ファイル

# language: jaフィーチャ: メールが送信できる SMTPクライアントとして、 メールを送信したい。 なぜなら、メールを利用者に届けたいから。

シナリオ: 接続するとバナーが返る 前提 サーバーが起動している もし 25番ポートに接続する ならば "220 "応答が返されること

50/63

Page 52: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

実行

% cucumber smtp.feature# language: jaフィーチャ: メールが送信できる SMTPクライアントとして、 メールを送信したい。 なぜなら、メールを利用者に届けたいから。

シナリオ: 接続するとバナーが返る # smtp.feature:7 前提サーバーが起動している # step_definitions/smtp_steps.rb:2 もし25番ポートに接続する # step_definitions/smtp_steps.rb:7 ならば"220 "応答が返されること # step_definitions/smtp_steps.rb:11

1 scenario (1 passed)3 steps (3 passed)0m0.002s

51/63

Page 53: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

HTML出力

% cucumber smtp.feature -f html -o /tmp/smtp.html

52/63

Page 54: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

HTML出力

53/63

Page 55: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

仕組み

features/├── smtp.feature└── step_definitions/ └── smtp_steps.rb

step_definitions 配下のスクリプトで対応する処理を実行

54/63

Page 56: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

step_definitions ファイル

前提 'サーバーが起動している' do system 'ps -ef | grep -q postfix/master' $?.should be_successend

もし '25番ポートに接続する' do @sock = TCPSocket.new('localhost', 25)end

ならば '"220 "応答が返されること' do @sock.gets.should =~ /^220 /end

55/63

Page 57: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

少し動的に

前提 'サーバーが起動している' do system 'ps -ef | grep -q postfix/master' $?.should be_successend

もし /(\d+)番ポートに接続する/ do |port| @sock = TCPSocket.new('localhost', port)end

ならば /\"(.*)\"応答が返されること/ do |status| @sock.gets.should =~ /^#{status}/end

56/63

Page 58: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

既存の定義を利用して定義

シナリオ: RCPT TO が受け付けられる 前提 MAIL FROM まで指定済み もし RCPT TO で tommy@localhost を指定する ならば "250 "応答が返されること

57/63

Page 59: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

既存の定義を利用して定義

前提 'MAIL FROM まで指定済み' do もし '25番ポートに接続する' ならば '"220 "応答が返されること' @sock.puts "MAIL FROM:<[email protected]>" ならば '"250 "応答が返されること'end

もし /RCPT TO で (.*) を指定する/ do |rcpt| @sock.puts "RCPT TO:<#{rcpt}>"end

58/63

Page 60: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

表を使う

シナリオアウトライン: 宛先に応じた応答が返る 前提 MAIL FROM まで指定済み もし RCPT TO で <宛先> を指定する ならば <結果>応答が返されること

例: | 宛先 | 結果 | | tommy@localhost | "250 " | | [email protected] | "550 " |

59/63

Page 61: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

結果

60/63

Page 62: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

Rails で使うと

feature ファイルに

○○に○○と入力する✓

○○ボタンをクリックする✓

○○と表示されていること✓

と書ける機能が用意されているらしい

61/63

Page 63: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

自動でできることは

機械にやらせよう

62/63

Page 64: RSpec と Cucumber

RSpec と Cucumber Powered by Rabbit 0.9.2

ご清聴ありがとうございました

63/63