0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rspecの始め方

Posted at

RSpecは、Rubyでテストを書くためのフレームワークです。アプリケーションが正しく動いているか確認するための「自動テスト」を簡単に書けます。

この記事では、RSpecを初めて使う方のために、Todoアプリを例にして導入から簡単なコード例までを解説します。

目次

  1. RSpecとは?
  2. RSpecを導入する
  3. RSpecのディレクトリ構成
  4. 用語の説明
  5. モデルのテスト
  6. コントローラのテスト
  7. システムテスト
  8. よくあるエラーと解決法
  9. 今後の展望

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リクエストや認証機能のテストにも挑戦してみましょう!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?