Help us understand the problem. What is going on with this article?

RSpecとりあえずこれを覚えておけば書ける!!

こんな人たちに読んでほしい!!

❶Rubyのテストコードの雰囲気だけでも掴みたい方

❷これからRubyでテストコード書かなきゃだけど戸惑っている方

❸JUnitとか他の言語でテストは書いたことあるけどRuby書きはじめてからテスト書いてないなあという方


学校でありましたね、テスト。社会人になってからテストがなくなってやっほいとなっている方は多いかもしれませんが、エンジニアにはテストがあります。しかも問題を自分で書かなければいけません!!つら、、、。

エクセルとかにテスト項目(このボタンを押したらどんな挙動を起こすか)を書いて○×をつけまくるテストも存在したりするのですが、自分たちで作ったプロダクトのメソッドがきちんと動くかチェックするプログラミングが存在します。ちゃんと○×っぽく結果が帰ってきます。

そして逆に、TDDという開発手法も存在して、先にテスト書いてから実際のプロダクトのコードをテストを元に記述する、なんてものもあります!

テスト書かないプロダクトもあったりはするのですが、基本的な部分はそんなに難しいわけではないので、ここで覚えてしまいましょう!

ここではRubyのテスト、RSpecについての基本的な書き方について紹介します。


1 まずはこれ覚えよう〜 describe, context, it , before, expect


基本的な文法を1つずつ覚えながら、テストを完成させましょう!

まずは describe!!

記述するとか描写するみたいな意味がありますよね。

Rspecではテストの最初の宣言みたいなイメージで取ってもらえるとわかりやすいかもしれません。

describe 'ユーザーモデルのテストです' do

end

こんな感じに文字列に何のテストか書いたりします。

ちなみにこのdescribeはネストできたりします!

describe 'ユーザーモデルのテストです' do

  describe ’メール周り’ do

  end

end

次にcontext!!

文脈みたいな意味がありますよね。ここでは条件みたいなものを書いたりします。if文にコード書くようなイメージで!

describe 'ユーザーモデルのテストです' do

  context 'メール送信成功' do

  end

  context 'メール送信失敗' do

  end

end

これで雛形みたいなのは大体できています。何も起きないじゃんって感じですが、これから具体的な中身を書いていきます。

before!!

テストの下準備、と覚えてもらえればOKです。

describe 'ユーザーモデルのテストです' do

  before do
    @user = User.create(id: '1', name: 'taro', email: hoge@hoge.com)
  end

  context 'メール送信成功' do

  end

  context 'メール送信失敗' do

  end

end

はい、やっとコードが出てきました。今下準備したのは、メール送信のメソッドをテストするために用意した、Userモデルのインスタンスです。Userがいないとメール送信できないので!!

ちなみにbeforeはcontextの中とか、ある程度自由に記述できます!状況に応じて使い分けましょう!

ちなみに何回もインスタンス作るのめんどくさいのでテスト用にFactoryBotなどのライブラリもありますが、ここでは飛ばします!

it、expect!!

ここでテストを実行するコードを書きます。

describe 'ユーザーモデルのテストです' do

  before do
    @user = User.create(id: '1', name: 'taro', email: hoge@hoge.com)
  end

  context 'メール送信成功' do
   it 'success' do
      expect(@user.semd_email('この文章を送ります')).to eq('送信に成功しました')
    end
  end

  context 'メール送信失敗' do
   it 'failed' do
      expect(@user.semd_email(nil)).to eq('送信に失敗しました')
    end
  end

end

expectは期待する、eqはequalのことで、等しい、という意味です。

expectのなかにテストしたいメソッドを書いて、eqの先にそのメソッドの戻り値を書きます。true、falseだったりする場合もあります!

これだけ覚えておけば、一応テストは大体かけます。ここまでの内容なら、そんなに難しくないと思います!

RSpec.describe ’テストしまーす‘ do

end

で囲うのをお忘れずに!

2 リファクタリングしてかっこよく〜 let, subject, is_expected

ここまでで大体のことは済むのですが、テストコード用に様々なメソッドが用意されています。今書いたコードを、それらを使ってリファクタリングしてみましょう!!

describe 'ユーザーモデルのテストです' do

  before do
    @user = User.create(id: '1', name: 'taro', email: hoge@hoge.com)
  end

  context 'メール送信成功' do
   it 'success' do
      expect(@user.semd_email('この文章を送ります')).to eq('送信に成功しました')
    end
  end

  context 'メール送信失敗' do
   it 'failed' do
      expect(@user.semd_email(nil)).to eq('送信に失敗しました')
    end
  end

end

まず、beforeのところ、短くしましょう!

describe 'ユーザーモデルのテストです' do

  let(:user) { create(id: '1', name: 'taro', email: hoge@hoge.com) }

  context 'メール送信成功' do
   it 'success' do
      expect(user.semd_email('この文章を送ります')).to eq('送信に成功しました')
    end
  end

  context 'メール送信失敗' do
   it 'failed' do
      expect(user.semd_email(nil)).to eq('送信に失敗しました')
    end
  end

end

letを使うと、インスタンスを作るのがこんなに簡単になります。beforeもいらないです。ここで、@userがuserになるのは気をつけて!!

次に、itのところ

describe 'ユーザーモデルのテストです' do

  let(:user) { create(id: '1', name: 'taro', email: hoge@hoge.com) }

  context 'メール送信成功' do
   it { expect(user.semd_email('この文章を送ります')).to eq('送信に成功しました') }
  end

  context 'メール送信失敗' do
   it { expect(user.semd_email(nil)).to eq('送信に失敗しました') }
  end

end

do endするまでもなく、こんなにスッキリかけます。そして最後の極め付け!!

subjectis_expected!!

describe 'ユーザーモデルのテストです' do

  let(:user) { create(id: '1', name: 'taro', email: hoge@hoge.com) }

  context 'メール送信成功' do
    subject { user.semd_email('この文章を送ります') }
   it { is_expected.to eq('送信に成功しました') }
  end

  context 'メール送信失敗' do
    subject { user.semd_email(nil) }
   it { is_expected.to eq('送信に失敗しました') }
  end

end

subjectは主題みたいな意味があります。主題のメソッドみたいな意味ですね!!ほんとはletの下にかけるメソッドにすればよかった、、、。letの下にかければ、メソッドを1つ書くだけで済みます!!

別なコードを例に出すと、

describe 'ユーザーモデルのテストです' do

  let(:user) { create(id: '1', name: 'taro') }
  subject { user.is_admin? }

  context 'admin?' do
    before do
     user.status = 'admin'
    end
   it { is_expected.to eq(true) }
  end

  context 'not admin?' do
    before do
     user.status = 'user'
    end
   it { is_expected.to eq(false) }
  end

end

こんな感じです!!書きながら無理やり考えた、、、笑。

こんな風に、let, subject, is_expectedを使うとテストコードを綺麗にかけます!!

ただし、やりすぎは注意です!!逆に読んでいる人がわけがわからなくなる可能性があるので、必要に応じて適宜使い分けましょう!!

3 まとめ

・describe, context, it , before, expect の書き方を覚えておけば基本的にはなんとかなる

・let, subject, is_expectedは必要に応じて使って、テストコードを綺麗に保とう!!

実はRspec学び始めて一週間くらいなのですが笑、このくらいのことはかけるレベルになります!!ていうくらいそんなに気構えるものではないです。要所要所うまくいかないところが絶対出てくるので、その時はグーグル先生に頼りましょう!!

もしかしたらコード間違えてるところあるかもなのでご指摘ください!!

 ここまで拙いながらもご一読いただきありがとうございます!これからもどうぞよろしくお願いします!!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした