RSpecは、Rubyでテストを書くためのフレームワークです。アプリケーションが正しく動いているか確認するための「自動テスト」を簡単に書けます。
この記事では、RSpecを初めて使う方のために、Todoアプリを例にして導入から簡単なコード例までを解説します。
目次
1. RSpecとは?
RSpecは、Rubyのコードをテストするためのツールです。「期待する動作」がちゃんと実現されているか確認するために使います。
2. RSpecを導入する
RSpecを使うには、Gemfileに以下を追加します。
Gemfile
group :development, :test do
gem 'rspec-rails', '~> 5.0.0'
end
その後、以下のコマンドを実行します。
ターミナル
bundle install
rails generate rspec:install
これで、spec/
ディレクトリが作成され、RSpecを使う準備が整います。
3. RSpecのディレクトリ構成
RSpecをインストール後のディレクトリ構成例は以下の通りです。
ディレクトリ構成図
spec/
├── models/
│ └── todo_spec.rb # モデルのテストファイル
├── requests/
│ └── todos_spec.rb # コントローラ(リクエスト)のテストファイル
├── system/
│ └── todos_spec.rb # システムテストのファイル
├── rails_helper.rb # Rails特化の設定ファイル
└── spec_helper.rb # RSpec全体の設定ファイル
4. テストに使用する用語の説明
用語 | 説明 |
---|---|
describe | テスト対象をグループ化します。クラスやメソッド名を指定することが多いです。 |
it | 個々のテストケースを表します。「何をテストしているか」を具体的に書きます。 |
expect | 実際の結果が、期待する結果と一致するかを確認します。 |
5. モデルのテスト
検証内容
- タイトルが存在する場合に有効であるかを検証します。
- タイトルが空の場合に無効であるかを検証します。
spec/models/todo_spec.rb
のコード例:
spec/models/todo_spec.rb
RSpec.describe Todo, type: :model do
describe 'バリデーション' do
it 'タイトルがある場合は有効である' do
todo = Todo.new(title: '買い物をする')
puts "検証対象: #{todo.inspect}"
expect(todo).to be_valid
end
it 'タイトルが空の場合は無効である' do
todo = Todo.new(title: nil)
puts "検証対象: #{todo.inspect}"
expect(todo).not_to be_valid
end
end
end
失敗時のログ
ターミナル
検証対象: #<Todo id: nil, title: nil, completed: nil>
F
Failures:
1) Todo バリデーション タイトルがある場合は有効である
Failure/Error: expect(todo).to be_valid
expected #<Todo id: nil, title: nil, completed: nil> to be valid, but got errors: Title can't be blank
修正内容
ターミナル
# 現状: モデルにバリデーションが存在しない
class Todo < ApplicationRecord
+ validates :title, presence: true
end
6. コントローラのテスト
検証内容
- GETリクエストで正しいテンプレートがレンダリングされるかを検証します。
spec/requests/todos_spec.rb
のコード例:
spec/requests/todos_spec.rb
RSpec.describe TodosController, type: :request do
describe 'GET /todos' do
it '正しいテンプレートがレンダリングされる' do
puts "リクエスト: GET /todos"
get todos_path
expect(response).to render_template(:index)
end
end
end
失敗時のログ例
失敗時のログ
ターミナル
リクエスト: GET /todos
F
Failures:
1) TodosController GET /todos 正しいテンプレートがレンダリングされる
Failure/Error: expect(response).to render_template(:index)
expecting <"index"> but rendering with <"errors/404">
修正箇所
修正内容
todo_controller.rb
# 現状: コントローラーのindexアクションが未実装
class TodosController < ApplicationController
def index
+ @todos = Todo.all
end
end
config/routes.rb
# 現状: ルーティングが存在しない
+ resources :todos, only: [:index]
7. システムテスト
検証内容
- 新しいTodoを作成し、画面に表示されるかを検証します。
spec/system/todos_spec.rb
のコード例:
spec/system/todos_spec.rb
require 'rails_helper'
RSpec.describe 'Todo管理機能', type: :system do
it 'Todoを作成し、表示する' do
puts "画面操作: 新しいTodoを作成"
visit new_todo_path
fill_in 'タイトル', with: '新しいTodo'
click_button '作成'
expect(page).to have_content('新しいTodo')
end
end
失敗時のログ例
失敗時のログ
ターミナル
画面操作: 新しいTodoを作成
F
Failures:
1) Todo管理機能 Todoを作成し、表示する
Failure/Error: expect(page).to have_content('新しいTodo')
expected to find text "新しいTodo" in "タスク一覧"
修正箇所
修正内容
todo_controller.rb
# 現状: createアクションがリダイレクトされていない
def create
@todo = Todo.new(todo_params)
if @todo.save
+ redirect_to todos_path, notice: 'Todoを作成しました'
else
render :new
end
end
8. よくあるエラーと解決法
エラー例: uninitialized constant Todo
- 原因: モデルが正しくロードされていません。
- 解決: モデルの名前やファイルパスを確認しましょう。
エラー例: expected: true, got: false
- 原因: バリデーションが期待通りに動作していない可能性があります。
- 解決: モデルに適切なバリデーションを追加しましょう。
9. 今後の展望
RSpecでは、今回の内容以外にもさまざまなテストを実装できます。次のような機能を追加した際には、それに対応するテストを記述してみましょう。
1. APIリクエストのテスト
- RESTfulなAPIエンドポイントに対するリクエストの挙動を確認する。
-
検証内容:
- 正しいデータをレスポンスとして返すか。
- 必要な認証情報がない場合に適切なエラーレスポンスを返すか。
-
例:
GET /api/todos
が正しいJSONデータを返すかをテスト。
2. 認証機能のテスト
- ユーザー認証や認可に基づくアクセス制限をテストする。
-
検証内容:
- ログインしたユーザーのみがアクセス可能なページで、未ログインの場合にリダイレクトされるか。
- 管理者のみが特定の機能を利用できるか。
3. パフォーマンステスト
- 大量のデータやリクエストに対してアプリケーションが期待通りに動作するかを確認する。
-
検証内容:
- 1000件のデータを読み込む際の処理時間が一定以内であるか。
- 高負荷時にエラーが発生しないか。
4. フロントエンドとの統合テスト
- Vue.jsやReactなどを利用したSPA(シングルページアプリケーション)で、バックエンドとフロントエンドの統合をテストする。
-
検証内容:
- APIレスポンスがフロントエンドで正しく描画されるか。
- ページ遷移やインタラクションが期待通りに動作するか。
5. サードパーティとの連携テスト
- 外部APIやサードパーティのライブラリとの連携を確認する。
-
検証内容:
- サードパーティのAPIに正しいリクエストを送信できているか。
- レスポンスエラー時に適切なエラー処理が行われるか。
次に目指すこと:
- 既存機能のテストカバレッジを拡大。
- モデルやコントローラー以外の部分(ジョブ、メール送信、API)をテスト対象に含める。
- システムテストをCapybaraと連携してユーザー視点の動作確認を行う。
RSpecを使ったテストを書き進めることで、アプリケーション全体の品質が向上します。次回はAPIリクエストや認証機能のテストにも挑戦してみましょう!