具体的な実装の記載はこちら
rspec
- 公式サイト https://relishapp.com/rspec
TDD(test-driven development)手法を取り入れたテストフレームワークです。
TDD(テスト駆動開発)とはなにか
プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き(これをテストファーストと言う)、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。
ざっくりと、、手順
- ある機能の振る舞いを洗い出し、そ
- 失敗するテストを書く(テストから書いているため失敗するのは当たり前。)
- 成功するテストを書く(仮実装をして、テスト側に問題があるのを防ぐ。それから明らかな実装を行う)
- リファクタリング(コードの重複をまとめたり、実装を本格化する)
この流れをグルグル回す
- 仮実装 => 絶対に成功するコードをかく
- 明らかな実装 => 実際の実装コード
- 同じ対象に対して違う角度からテストする(三角測量)
- railsでのrspecの実行の仕方
bundle exec rspec rspecファイルのpathを指定
- optionで-fbをつけると見やすくなる(cfo-a)
出力結果の見方(-fbオプションを加えた場合)
- describeまたはcontextの説明がインテンドでわかりやすく表示されている
- 緑が成功
- 赤が失敗
- Failures: 以降に具体的な間違いを指摘してくれる
- expected 期待した値
- got 実際の値 => 一致しないのでテスト失敗している
書き方
describe
- テスト対象のグループ分け
- 入れ子できる
- グループの分け方がものだった場合こっち
- トップレベルのdedcribeはよくクラス名を書くことが多い
describe "クラスのテスト" do
end
describe クラス名 do
end
context
- テスト対象のグループ分け
- describeと同じ
- グループの分け方が状況だった場合こっち
expect "when method exists" do
end
- 説明文はrspec実行する時に-fdをつけたときに表示されるので、わかりやすいように名前をつけとくのがミソ
it
- テスト対象に対して、期待する振る舞いを記載
- 説明文は省略できる
- 例 calcオブジェクトのaddメソッドに引数2,3を渡した時の返り値が5になる
it "given 2 and 3, returns 5" do
calc = Calc.new
expect(calc.add(2, 3)).to eq(5)
end
# 省略形
it {
calc = Calc.new
expect(calc.add(2, 3)).to eq(5)
}
- 省略するとrspecが自動で説明文描いてくれる
should eq 5
- 仕様の振る舞いだけ書いておきたい場合。
it "振る舞い"
-
黄色で表示
-
itで期待する振る舞いを書く時に使う記号 -> macharという
- 公式サイトの資料 https://relishapp.com/rspec/rspec-expectations/v/3-6/docs/built-in-matchers
- eq =
- not_to eq !=
- to be ture
- to be false
- to be >
- to be <
- to_between(a,b),inclusive a~bの間、a,bを含む
- to respond_to(:abc) オブジェクトにabcメソッドがあるか?
- to be_integer?
expect(calc).to respond_to(:add)
# integer? empty?
expect(calc.add(2, 3).integer?).to be true
expect(calc.add(2, 3)).to be_integer
before
- exampleの共通化処理をブロックにまとめる
# インスタンス化処理を共通化
before(:option) do
@calc = Calc.new
end
- オプション
- 省略したらexampleがデフォルトで入る
- example それぞれのexampleで実行したい
- context 最初の一回目のexampleだけ実行
- exampleをまたがって変数を使用する場合は@を前につける
subject
- 主対象の操作を管理できる
- describeにクラス名を指定した場合、subjectでインスタンス化できる。
# desribeにCalcクラスを指定した場合、Calcオブジェクトになる
expect(subject.add(2,3)).to eq(5)
- subjectをそのまま使うと何を表しているのかわからなくなるので
subject(:hoge){ Hoge.new }
- こう宣言しとけばhogeを各ブロックで使える
- beforeと同じだが、exampleで使う時は@要らない。シンボルで管理できる。
let
- ほぼsubjectと同じ役割
- 主対象以外の変数などの操作を管理する
let(:tax){ 0.08 }
it{expect(seminar.price(100,tax)).to eq(108)}
- 遅延評価される
- 遅延評価ではなく、example毎で必ず実行したい場合は
let!
をつかう - exsample毎にキャッシュされる
test doubl
-
実装はまだだけどテストはしたい場合に使用
-
method stub => 実装していないけれどテストに使えるメソッドを作る。または、テストする必要のない処理などの返り値を指定する
- allowでseminarというオブジェクトを選択し、receiveでそのオブジェクトのexist?メソッドを選択、その返り値をand_reternで指定している
- receive_message_chainでメソッドチェーンで複数していできる。
- withで引数を渡す
- 引数を持たないメソッドにはno_argsをしていてあげる
-
message expectation
-
呼ばれなかったらfalseでテストは失敗する