kouの技術的メモ

学習した内容の定着やアウトプット用に開設しました

成果物の作成2作品目⑨ 予定管理サービス  インテグレーションテスト実装

今回は全体のインテグレーションテストを作り込んでいきます。

まずはヘッダーレイアウトのインテグレーションテストです。

omniauthを使ったログイン部分を実装していきます。

minitestでテストを書いているのですが、日本語で検索してもomniauthのテスト方法がRspecを用いた方法しか出てこず(ominiauth英語公式ページもRspecでの方法)、めっちゃ詰まりました…

英語圏のwebページにて少しだけ断片的な情報が見つかったので、試行錯誤しながら実装してみました。

loginメソッドと、後で使うのでlogoutメソッドを作りました。

test/test_helper.rb

  setup do
    OmniAuth.config.test_mode = true
  end
  
  def login
  OmniAuth.config.add_mock(:twitter, { uid: '12345678910' })
  get '/auth/twitter'
  request.env['omniauth.env'] = OmniAuth.config.mock_auth[:twitter]
  get '/auth/twitter/callback'
  end

  def logout
    delete '/logout'
  end

テストは通るようなので、これで大丈夫そうです。

条件分岐部分で少しつまりましたが、こんな感じで、

  def setup
    @user = users(:user)
  end

  test "スケジュール新規作成機能に関するテスト)" do                             #createアクションのif文条件分岐3つ網羅
    login(@user)                                                                        #test_helperのloginメソッド
    get new_schedule_path                                                        
    assert_select 'h1', "スケジュール入力ページ" 
    assert_select 'input[type="text"]'
    # 無効な送信 条件分岐1
    assert_no_difference 'DaySchedule.count' do 
      post schedule_index_path, params: { day_schedule: { day_schedule: "" } } 
    end
    assert_equal '入力値が空か、255文字以上です。保存に失敗しました', flash[:danger]
    assert_template 'schedule/new'
    # 有効な送信
    assert_difference 'DaySchedule.count', 1 do 
      post schedule_index_path, params: { day_schedule: { day_schedule: "テスト用文章" } } 
    end
    follow_redirect! 
    assert_equal 'スケジュールの作成に成功しました!', flash[:success]
    assert_template 'time_schedules/new'
    # もう一度スケジュール新規作成
    get new_schedule_path                                                         
    assert_no_difference 'DaySchedule.count' do 
      post schedule_index_path, params: { day_schedule: { day_schedule: "テスト用文章2" } }
    end
    # 無効な送信
    assert_equal 'すでにあなたの予定は存在します、ヘッダーリンクの「予定とユーザー情報」ページから、一度予定を削除してからリトライしてください', flash[:danger]
    assert_template 'schedule/new'
    # スケジュール削除
    get user_path(@user)
    assert_difference 'DaySchedule.count', -1 do 
      delete schedule_path(@user.day_schedule.first)
    end
    follow_redirect! 
    assert_equal 'スケジュールを削除しました', flash[:success]
    assert_template 'home/index'
    end
end

合わせてフィクスチャーも各モデル同士のリレーションシップを考慮して書きました。

/schedule/test/fixtures/users.yml

user:
  id: 1
  provider: twitter
  uid:  123
  user_name:  user

other_user:
  id: 2
  provider: twitter
  uid: 456
  user_name:  other_user
  
<% 7.times do |n| %>
user_<%= n %>:
  id: <%= n + 3 %>
  provider: twitter
  uid:  <%= n + 3 %>
  user_name:  <%= "User #{n}" %>
<% end %>

test/fixtures/day_schedules.yml

one_day:
  day_schedule: today's_schedule
  user: other_user

test/fixtures/time_schedules.yml

first_time:
  time_schedule: test
  start_time:  1900-00-01 01:00:00
  end_time:  1900-00-01 02:00:00
  day_schedule: one_day

全部ブログに書き出すと膨大になってしまうので、とりあえずこれぐらいにしておきます。

今回、テストのominiauthのログインが分からず、だいぶ時間を消費したり、

ビューファイルがテストしづらいhtmlのコーディングになっていたので書き直したり、

ユーザーを削除した際にログアウトできていないバグを見つけてコントローラを書き直したり、

効率的なテストの書き方をRails テスティングガイドを見ながらあれこれ考えて書いたり、

フィクスチャーファイルも何回か書き直したり、

大分時間がかかりましたが、様々な知見が得られたと思います。

バグフィックスも終わったので、後はコードを最終チェックしていよいよ完成にしたいと思います!