Ruby初心者向けテストコードの書き方
こんな人たちに読んでほしい!!
❶Rubyのテストコードの雰囲気だけでも掴みたい方
❷これからRubyでテストコード書かなきゃだけど戸惑っている方
❸JUnitとか他の言語でテストは書いたことあるけどRuby書きはじめてからテスト書いてないなあという方
1 そもそもテストコードって??
学校でありましたね、テスト。社会人になってからテストがなくなってやっほいとなっている方は多いかもしれませんが、エンジニアにはテストがあります。しかも問題を自分で書かなければいけません!!つら、、、。
エクセルとかにテスト項目(このボタンを押したらどんな挙動を起こすか)を書いて○×をつけまくるテストも存在したりするのですが、自分たちで作ったプロダクトのメソッドがきちんと動くかチェックするプログラミングが存在します。ちゃんと○×っぽく結果が帰ってきます。
そして逆に、TDDという開発手法も存在して、先にテスト書いてから実際のプロダクトのコードをテストを元に記述する、なんてものもあります!
テスト書かないプロダクトもあったりはするのですが、基本的な部分はそんなに難しいわけではないので、ここで覚えてしまいましょう!
ここではRubyのテスト、Rspecについての基本的な書き方を紹介します。
2 まずはこれ覚えよう〜 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
で囲うのをお忘れずに!
3 リファクタリングしてかっこよく〜 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するまでもなく、こんなにスッキリかけます。そして最後の極め付け!!
subjectとis_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を使うとテストコードを綺麗にかけます!!
ただし、やりすぎは注意です!!逆に読んでいる人がわけがわからなくなる可能性があるので、必要に応じて適宜使い分けましょう!!
4 まとめ
・describe, context, it , before, expect の書き方を覚えておけば基本的にはなんとかなる
・let, subject, is_expectedは必要に応じて使って、テストコードを綺麗に保とう!!
実はRspec学び始めて一週間くらいなのですが笑、このくらいのことはかけるレベルになります!!ていうくらいそんなに気構えるものではないです。要所要所うまくいかないところが絶対出てくるので、その時はグーグル先生に頼りましょう!!
もしかしたらコード間違えてるところあるかもなのでご指摘ください!!
ここまで拙いながらもご一読いただきありがとうございます!これからもどうぞよろしくお願いします!!
この記事が気に入ったらサポートをしてみませんか?