はじめに
Rubyをあまりさわったことない初心者向けの内容です。
細かいところは置いておいて、とりあえずRSpecでテスト書く→コード実装のような、超シンプルなチュートリアルをまとめてみました。
- RSpecはポピュラーなテストフレームワーク
- DSLとかでフォーマットされてて、自然言語(英語)っぽくテストが書ける
- David Chelimsky氏のブログでもチュートリアルがある(※2007年のエントリ)
- 本ならThe RSpec Bookもあるよ!!4,410円。
下準備
install
$ gem install rspec
rspec -- init
$ rspec --init
create spec/spec_helper.rb
create .rspec
シンプルなチュートリアル
以下の差分はこちら: https://github.com/luckypool/testing-with-rspec
(1) テスト対象を決める
- 今回は
/lib/dog.rb
とかを想定する - まだコードは書かなくてOK
- どんなclassかは決めておく。
(2) テストファイルをつくる
- こんな感じ
spec/lib/dog_spec.rb
- <name_of_spec>_spec.rb というように
_spec.rb
というsuffixつける
- <name_of_spec>_spec.rb というように
(3) 最初のテストコード
spec/lib/dog_spec.rb
require "spec_helper"
describe "Dog" do
it "is named 'Pochi'"
end
- name が 'Pochi' であるインスタンスが生成されると期待を込めて。
- 実行結果は・・・
$ rspec spec/lib/dog_spec.rb
*
Pending:
Dog is named 'Pochi'
# Not yet implemented
# ./spec/lib/dog_spec.rb:4
Finished in 0.00025 seconds
1 example, 0 failures, 1 pending
- 未実装でペンディングされてるよ!って結果になりました。
(4)対象モジュールを読み込んだ上でペンディングする
lib/dog.rb
class Dog
end
- まだ空っぽです
spec/lib/dog_spec.rb
require "spec_helper"
require "dog"
describe Dog do
it "is named 'Pochi'"
end
- 実際にモジュールを読み込んでみます。
- 実行結果は・・・
$ rspec spec/lib/dog_spec.rb
*
Pending:
Dog is named 'Pochi'
# Not yet implemented
# ./spec/lib/dog_spec.rb:5
Finished in 0.00035 seconds
1 example, 0 failures, 1 pending
- まだペンディング中!
(5)期待通りに落ちるテストを書く
spec/lib/dog_spec.rb
require "spec_helper"
require "dog"
describe Dog do
it "is named 'Pochi'" do
dog = Dog.new
expect(dog.name).to eq 'Pochi'
end
end
- 英語っぽくテストがかけますね!
- 追記。上記の例では expect を使っていますが、コメントで頂いたような書き方もできます!
- 参考に追記したエントリや、まわりのRubyistに学んでシャレオツなコードを書きたいですね :)
- 実行結果は・・・
$ rspec spec/lib/dog_spec.rb
F
Failures:
1) Dog is named 'Pochi'
Failure/Error: expect(dog.name).to eq 'Pochi'
NoMethodError:
undefined method `name' for #<Dog:0x007fea60987400>
# ./spec/lib/dog_spec.rb:7:in `block (2 levels) in <top (required)>'
Finished in 0.00031 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/lib/dog_spec.rb:5 # Dog is name 'Pochi'
- ちゃんと落ちました。
(6)テストが通るように実装する
lib/dog.rb
class Dog
attr_accessor :name
def initialize(name="Pochi")
@name = name
end
end
- 実行結果はもちろん・・
$ rspec spec/lib/dog_spec.rb
.
Finished in 0.00122 seconds
1 example, 0 failures
- パスしましたね! :)
(7)テスト追加して実装を繰り返す
- こんな感じでテストを追加してきましょう
spec/lib/dog_spec.rb
require "spec_helper"
require "dog"
describe Dog do
it "is named 'Pochi'" do
dog = Dog.new
expect(dog.name).to eq 'Pochi'
end
it "has fangs" do
dog = Dog.new
expect(dog.fangs).to eq 2
end
it "is alived" do
dog = Dog.new
expect(dog).to be_alived
end
end
lib/dog.rb
class Dog
attr_accessor :name, :fangs
def initialize(name="Pochi")
@name = name
@fangs = 2
end
def alived?
true
end
end
- グリーン!!
$ spec spec/lib/dog_spec.rb
...
Finished in 0.00249 seconds
3 examples, 0 failures
参考
Expectations
テストコードは expect(hogehoge).to be_true
なんて風に書けます。
他にも色々と表現できるのですが、詳しくは下記のREADMEに載っています。
あと、should
という expectation もありますが、expect
の方が新しいものだそうです。
- RSpecのshouldはもう古い!新しい記法expectを使おう!
-
should and should_not syntax に説明があります。
- By default, both
expect
andshould
syntaxes are available. In the future, the default may be changed to only enable theexpect
syntax.
- By default, both
- 新規テストには expect を使いたいですね :)
以上!