新年はげましておめでとうございます。
はじめに
- ずっとやらなきゃって思って引きずってきた Rspec をやってみる
- ちゃんとうんちくを押さえておきたいけど、まずは写経したりサンプルを弄ったりしながら
- 合わせて Rspec を Travis CI で実行させてみる
以下、色々と試しながら書いているので間違い等があると思われるので、適宜、アップデートしていく。
参考
上記記事がとても参考になった。有難うございます。今後の為にもリンクを貼っておく。
Hello Rspec
何はともあれ
うんちくは後回しにしてサンプルスクリプトを使って Rspec をざっくりと体験してみる。
サンプル Ruby スクリプト
以下のようなスクリプトを zura.rb という名前で用意する。
class Zura def hage(str) str end end watashi = Zura.new() p watashi.hage("私はズラではない")
実行すると以下のような結果が得られる。
$ ruby zura.rb "私はズラではない"
本当にズラではありません。
テスト
テストと称してして zura_spec.rb を以下のように作成。
require_relative 'zura' describe Zura, "のテスト" do before do @watashi = Zura.new() end context '#hage の引数が "私はズラ" の場合' do before do @arg = "私はズラ" end it '私はズラ' do expect(@watashi.hage(@arg)).to eq '私はズラ' end end context '#hage の引数が指定されていない場合' do it '引数エラーとなる' do expect{@watashi.hage}.to raise_error(ArgumentError) end end end
テスト実行
以下のようにテストを実行する。
$ rspec --color -fd zura_spec.rb Zura のテスト #hage の引数が "私はズラ" の場合 "私はズラ" が返ってくる #hage の引数が指定されていない場合 引数エラーとなる Finished in 0.00176 seconds (files took 0.08805 seconds to load) 2 examples, 0 failures
(追記)Travis CI でズラ
うんちく
Rspec とは
こちらより抜粋。
RSpecとは、Rubyで書かれたプログラムの動作を確認するための、テストコードを記述・実行するためのフレームワークのことです。実際に動くプログラムの動作のことを振る舞い(ビヘイビア)と呼ぶことから、それまでのテスト駆動開発のやり方をビヘイビア駆動開発(BDD)と呼ぶようになっています。
用語 / 命令のおさらい
前述のサンプルスクリプトからピックアップ。詳細については参考にさせて頂いた記事より抜粋させて頂いた。重ねて有難うございます。
用語 / 命令 | 詳細 | 備考 |
---|---|---|
describe | テストのグループ化を宣言する | |
context | テストを条件別にグルーピングする | |
it | テストを example という単位にまとめる |
|
before | example 実行前に呼ばれる |
before do ... end |
expect | expect(foo).to eq bar で記述して「foo が bar であることを期待する」という意味になる |
「エクスペクテーション」と呼ばれる |
マッチャ | マッチャ(matcher)は「期待値と実際の値を比較して、一致した(もしくは一致しなかった)という結果を返すオブジェクト」 | こちらより抜粋、マッチャの一覧はこちらが参考になる |
モック | 「あるオブジェクトのメソッドが[引数]で呼ばれることを期待して、呼び出された時には[戻り値]を返すようにしたい場合」に利用する | こちらより抜粋 |
スタブ | 「あるオブジェクトのメソッドが呼び出された時に、特定の戻り値を返すようにしたい場合」に利用する | こちらより抜粋 |
その他にも用語や命令がありそうだけど...取り急ぎ。
例
前述のサンプルを再掲。
# Zura Class のテストを宣言 describe Zura, "のテスト" do # example 実行前に Zura Class から @watashi インスタンスを生成する before do @watashi = Zura.new() end # 条件「#hage の引数が "私はズラ" の場合」 context '#hage の引数が "私はズラ" の場合' do # example 実行前に @arg に "私はズラ" を代入 before do @arg = "私はズラ" end # hage メソッドの返り値として "私はズラ" を期待する example を実行 it '私はズラ' do expect(@watashi.hage(@arg)).to eq '私はズラ' end end (snip) end
も少し踏み込んで
教材
スクリプト
LXD でコンテナ一覧を取得する部分。
require "net_http_unix" class Client def initialize(uri) @uri = uri end def client NetX::HTTPUnix.new(@uri) end def list_containers req = Net::HTTP::Get.new("/1.0/containers") resp = client.request(req) return resp.body end end
hoge.rb という名前で保存しておく。
テストスクリプト
以下のようなテストスクリプトを作成。
require 'hoge' describe Client do describe '#initialize' do context '引数 uri が設定されている場合' do before do @uri = 'unix:///var/lib/lxd/unix.socket' end it '引数は String である' do expect(@uri).to be_a_kind_of(String) end end context '引数 uri が設定されていない場合' do it '引数エラーとなる' do expect{Client.new}.to raise_error(ArgumentError) end end end describe '#client' do context '引数 uri が設定されている場合' do before do @uri = 'unix:///var/lib/lxd/unix.socket' end it 'object が生成される' do c = Client.new(@uri) expect(c.client).to be_a_kind_of(Object) end end end describe '#list_containers' do context '引数 uri が正しく設定されている場合' do before do uri = 'unix:///var/lib/lxd/unix.socket' @res = '{"type":"sync","status":"Success","status_code":200,"metadata":["/1.0/containers/test01"],"operation":""}' @c = Client.new(uri) allow(@c).to receive(:list_containers).and_return(@res) end it 'コンテナ一覧が String で取得出来る' do expect(@c.list_containers).to be_a_kind_of(String) end it 'コンテナ一覧が取得出来る' do response = @c.list_containers expect(response).to eq @res end end end end
hoge_spec.rb というファイル名で保存しておく。
ローカルホストでテストを実行する
$ rake spec /usr/local/bin/ruby -I/usr/local/lib/ruby/gems/2.1.0/gems/rspec-support-3.4.1/lib:/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.4.1/lib /usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.4.1/exe/rspec --pattern spec/\*\*/\*_spec.rb --color -fd Client #initialize 引数 uri が設定されている場合 引数は String である 引数 uri が設定されていない場合 引数エラーとなる #client 引数 uri が設定されている場合 object が生成される #list_containers 引数 uri が正しく設定されている場合 コンテナ一覧が String で取得出来る コンテナ一覧が取得出来る Finished in 0.00738 seconds (files took 0.12878 seconds to load) 5 examples, 0 failures
Travis CI でテストを実行する
テストを Travis CI で実行させたいので、事前に Travis CI と GitHub のリポジトリを連携させておく。
上図のように連携を ON にしておくだけ。
リポジトリに push すると以下のようにテストが実行されて結果が出力される。
おお。
ということで
引き続き
- マッチャ、モック、スタブ等についてメモっていきたい
- テストを書くというのはセンスが必要な気がしているが、まずは基礎をちゃんとやりたい
- どんな風に Rspec を勉強していいのかすら解らないのが辛い
- Travis CI 楽しい