- 公開日: 2021年04月07日
【Ruby on Rails】Rspecのテストをやってみよう!
プログラミング初心者の中には、Rspecに関して苦手意識を持っている方もおられるかもしれません。実はRspecは覚える構文も少なく、意外と難しくはありません。
本記事では実際にRspecのテストコードを書き、理解を深めていけるようになっています。ぜひ参考にしてみてください。
アプリケーションの雛形を作成しよう
まずはRspecでテストをおこなうために、「Scaffold」を使ってアプリケーションの雛形を作成していきます。Scaffoldはアプリケーションを動かすのに、必要最低限の機能を備えたものを簡単に作成可能です。
まずはターミナル(コマンドプロンプト)を開き、下記コマンドを実行してください。
rails new rspec_practice
rails g scaffold post title:string content:string
rails db:migrate
rails s
ここまでのコマンドを実行すると、下画像が表示されます。
次にScaffoldにより作成されたPostモデルに対して、バリデーションを設定していきます。バリデーションとは、例えば入力フォームに何も入力されていないと、エラーを発生させる機能を作るために必要なものです。
それでは、「post.rb」を開き、下記コードを貼り付けてください。
class Article < ApplicationRecord
validates :title, presence: true
validates :title, length: {minimum:2, maximum: 10}
validates :content, presence: true
end
モデルに関連するファイルを編集したので、一度サーバーを再起動しましょう。 下記コマンドを実行すると再起動できます。
//サーバーを停止
Ctrl + C
//サーバーを起動
rails s
ここまででアプリケーションの準備は完了です。
Rspecの準備をしよう
この章では、Rspecでテストをおこなうために必要なgemのインストールやテストのコードについて解説していきます。まずはGemfileを開き、下記コードを追記してください。
Rspecを用いたテストは開発環境でおこなうものなので、「group :development do」のグループ内に「gem 'rspec-rails'」と記載しています。
gemをインストールするために、ターミナルで「bundle install」を実行してください。次にテストコードの実行に必要なファイルを準備しいきましょう。
ターミナルで下記コマンドを実行してください。
rails g rspec:install
//下記のファイルが作成される
//.rspec & spec/spec_helper.rb & spec/rails_helper.rb
rails g rspec:model article
//下記のファイルが作成される
//spec/models/post_spec.rb
コマンドを実行すると、「post_spec.rb」など必要なファイルが作成されたことが分かります。
Rspecのテストコードを書いてみよう①
テストをおこなうためのファイルを作成できたので、実際にテストコードを書いていきます。細かい構文に関しては、後ほど解説するので、まずはRspecのテストの雰囲気をつかんでください。
では、「post_spec.rb」を開き、下記コードを貼り付けてください。デフォルトで書かれている内容は、消して問題ありません。
require 'rails_helper'
RSpec.describe Post, type: :model do
context "タイトルと内容が入力されている場合" do
let!(:post) do
Post.new({title: "Rspecのテスト", content:"Rspecにトライしてみよう!"})
end
it '記事を保存できる' do
expect(post).to be_valid
end
end
end
Rspecでテストコードを書く際は、3点を意識しましょう。
①テストで何を確認したいのか決める
②確認するために必要なデータを作成する
③①で決めたことが実際に起こるか確認する
上記のコードでは、下記3点をおこなっています。
①タイトルが2文字以上10文字以下かつコンテンツが入力されている場合に、エラーが出ないことを確認する
②Post.new….でダミーデータを作成する
③「bundle exec rspec spec/models/post_spec.rb」でテストを実行する
ではターミナルを開き、下記コマンドを実行して結果を確認してください。
bundle exec rspec spec/models/post_spec.rb
//実行結果
.
Finished in 0.06612 seconds (files took 5.6 seconds to load)
1 example, 0 failures
緑の文字が現れたら、テストに問題なく合格したしるしです。では次にテストに失敗するケースをみていきましょう。
「post_spec.rb」を開き、下記コードに書き換えてください。 今回のテストでは、①タイトルが10文字以上②コンテンツが空のため、バリデーションエラーが発生するはずです。
require 'rails_helper'
RSpec.describe Post, type: :model do
context 'タイトルと内容が入力されている場合' do
let!(:post) do
Post.new({ title: 'これは10文字以上のタイトルです。', content: '' })
end
it '記事を保存できる' do
expect(post).to be_valid
end
end
end
コードを貼り付けたら、ターミナルで下記コマンドを実行して結果を確認してみましょう。
bundle exec rspec spec/models/post_spec.rb
//実行結果
F
Failures:
1) Post タイトルと内容が入力されている場合 記事を保存できる
Failure/Error: expect(post).to be_valid
expected #<Post id: nil, title: "これは10文字以上のタイトルです。", content: "", created_at: nil, updated_at: nil> to be valid, but got errors: Title is too long (maximum is 10 characters), Content can't be blank
# ./spec/models/post_spec.rb:9:in `block (3 levels) in <top (required)>'
Finished in 0.1769 seconds (files took 6.48 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/models/post_spec.rb:8 # Post タイトルと内容が入力されている場合 記事を保存できる
上記のエラー文が赤文字で表示されればOKです。
Rspecの構文を理解しよう
ここまででRspecの雰囲気をつかめたと思うので、テストコードを書く際に必要な構文について解説していきます。
テストの宣言をおこなう「describe」
「describe」は、「〇〇を確認するテストを行います」という宣言をするための構文です。本記事では、下記のように使用されています。
RSpec.describe Post, type: :model do
ちなみにdescribeのあとは日本語でもOKです。
RSpec.describe “記事”, type: :model do
テストで確認することを宣言する「it」
テストで確認することは、「it」を使って表現可能です。本記事では、下記のように使用されています。
it '記事を保存できる' do
Rspecのテストコードは誰がみても分かるように記述されているのがベストです。 例えば下記のような記述だと、「何を保存するのか」という疑問が生まれてしまうので注意してください。
it '保存できる' do
主語と述語を意識して書くと良いでしょう。
「〜の場合は」を表現する「context」
「〜の場合は」を表現する場合、「context」を使用します。本記事では下記のように使用されています。
context 'タイトルと内容が入力されている場合' do
itの場合と同じく、誰がみても分かるように宣言するのがコツです。
変数を宣言する「let!」
最後に「let!」についてみていきましょう。テストコードで使用する変数は、「@post」のようなインスタンス変数で宣言するのではなく、「let!」を使うのが一般的です。
本記事では、下記のように使用しています。
let!(:post) do
仮にインスタンス変数を用いて、テストコードを書き直すと下記のようになります。 はじめは慣れないかもしれませんが、積極的に「let!」を使いましょう。
RSpec.describe Post, type: :model do
context 'タイトルと内容が入力されている場合' do
before do
@post = Post.new({ title: 'RSpecテスト', content: 'RSpecテストの内容' })
end
it '記事を保存できる' do
expect(@post).to be_valid
end
end
end
Rspecのテストコードを書いてみよう②
Rspecで使用する構文について理解できたので、もう1つテストコードを書いてみましょう。「post_spec.rb」を開き、下記コードに書き換えてください。
require 'rails_helper'
RSpec.describe Post, type: :model do
context 'タイトルの文字が1文字の場合' do
let!(:post_title_one_letter) do
Post.create({ title: 'あ', content: 'RSpecテストの内容' })
end
it 'タイトルのエラーメッセージが出ること' do
expect(post_title_one_letter.errors.messages[:title][0]).to eq('is too short (minimum is 2 characters)')
end
end
end
コードを貼り付けたら、下記コマンドを実行して結果を確認してください。 緑の文字が表示されればOKです。
bundle exec rspec spec/models/post_spec.rb
//実行結果
.
Finished in 0.10166 seconds (files took 4.76 seconds to load)
1 example, 0 failures
ではテストコードについてもう少し詳しくみていきましょう。下記コードは、タイトルが2文字以下の場合に、「is too short (minimum is 2 characters」というエラーメッセージが表示されることを確認しています。
expect(post_title_one_letter.errors.messages[:title][0]).to eq('is too short (minimum is 2 characters)')
実はバリデーションのエラーメッセージは「errors.messages」に格納されています。確認のため、下記コードをテストコードに貼り付けてください。
RSpec.describe Post, type: :model do
context 'タイトルの文字が1文字の場合' do
let!(:post_title_one_letter) do
Post.create({ title: 'あ', content: 'RSpecテストの内容' })
end
it 'タイトルのエラーメッセージが出ること' do
# 追加
puts post_title_one_letter.errors.messages
expect(post_title_one_letter.errors.messages[:title][0]).to eq('is too short (minimum is 2 characters)')
end
end
end
再度ターミナルで下記コマンドを実行して、結果を確認すると下記の結果が追加されています。これがエラーメッセージの正体です。
```Ruby
{:title=>["is too short (minimum is 2 characters)"]}
エラーメッセージは上記のようにハッシュになっているので、その中身を取り出すために、「post_title_one_letter.errors.messages[:title][0]」という記述をしています。
これでRspecに関する解説は以上です。 お疲れ様でした。
\Rubyでのサービス開発スキルが身に付く/
まとめ
Rspecのテストについて解説してきました。本記事で紹介した構文を再度復習してみて、理解を深めてみてはいかがでしょうか。
- この記事を書いた人
- ヤマモト