LoginSignup
0
0

More than 3 years have passed since last update.

投稿機能 統合テストの実装

Posted at

今回ポートフォリオ作成中にでたエラーの解決策を備忘録も含め、同じところでつまづかれている方などいましたら、ご参考にして頂けましたら幸いです。

投稿機能では画像つきの機能を取り入れてまして、
でたエラーに関してが、

Capybara::ElementNotFound: Unable to find field "post[images][]" that is not disabled
from /Users/takuya/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.35.3/lib/capybara/node/finders.rb:303:in `block in synced_resolve'

上記のエラーでした。

アウトプットの前に、
rspec
factory.bot
上記は導入済みで、進めさせていただきます。

ちなみにかなり時間を取られました💦

投稿機能統合テスト記述

RSpec.describe '写真テキスト投稿', type: :system do
  before do
    @user = FactoryBot.create(:user)
    @post_name = Faker::Lorem.sentence
  end
  context '写真テキスト投稿ができるとき'do
    it 'ログインしたユーザーは新規投稿できる' do
      # トップページに移動する
      visit root_path
      # トップページにログインページへ遷移するボタンがあることを確認する
      expect(page).to have_content('LOGIN')
      # ログインページへ遷移する
      visit new_user_session_path
      # 正しいユーザー情報を入力する
      fill_in 'Eメール', with: @user.email
      fill_in 'パスワード', with: @user.password
      # ログインボタンを押す
      find('input[name="commit"]').click
      # トップページへ遷移することを確認する
      expect(current_path).to eq(root_path)
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 新規投稿ページへのリンクがあることを確認する
      expect(page).to have_content('PUSH 投稿')
      # 投稿ページに移動する
      visit new_post_path
      # フォームに情報を入力する
      fill_in 'post[images][]', with: "public/images/test_image.jpg"
      fill_in 'post[name]', with: @post_name
      # 送信するとPostモデルのカウントが1上がることを確認する
      expect{
        find('input[name="commit"]').click
      }.to change { Post.count }.by(1)
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 写真投稿一覧ページには先ほど投稿した内容の写真テキストが存在することを確認する(画像)
      expect(page).to have_selector("img[src$='test_image.png']")
      # 写真投稿一覧ぺージには先ほど投稿した内容の写真テキストが存在することを確認する(テキスト)
      expect(page).to have_content(@post_name)
    end
  end
  context '写真投稿ができないとき'do
    it 'ログインしていないと新規投稿ページに遷移できない' do
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 新規投稿ページへのリンクがない
      expect(page).to have_no_content('nPUSH 投稿')
    end
  end
end

fill_in 'post[images][]', with: "public/images/test_image.jpg"
の上にbinding.pryを入れて、上記コードを入力すると画像が挿入できない状態でした。

要素中にinputタグのname要素を入れ込んでいるのになぜエラーが出るのかと四苦八苦していました。

一度頭を整理して、fill_in意外にも画像挿入する方法はないかと調べたところ、

attach_file

というメソットが引っかかりました。

そこでfill_inを削除してattach_fileメソットの記述を行いました。

変更前

# フォームに情報を入力する
      fill_in 'post[images][]', with: "public/images/test_image.jpg"
      fill_in 'post[name]', with: @post_name

変更後

# フォームに情報を入力する
      attach_file('post[images][]', image_path, make_visible: true)
      fill_in 'post[name]', with: @post_name

上記を記述変更を行い、今すぐにでも実装を行いたかったのですが、焦ってはいけませんでした

変更後の記述の中にimage_pathを代入していることから、
フォームに情報を入力する
の統合テストを行う前に、添付する画像を定義する記述を行いました。
そうしないとなんの画像を指定しているのかわからないためです

そして、

# 添付する画像を定義する
      image_path = Rails.root.join('public/test_image.png')
      # フォームに情報を入力する
      attach_file('post[images][]', image_path, make_visible: true)
      fill_in 'post[name]', with: @post_name

フォーム情報を入力するの前に、画像を定義する記述を行い、無事テストが行える状況になりました。

実装を行うと、問題なく統合テストを行うことができました

完成コード

RSpec.describe '写真テキスト投稿', type: :system do
  before do
    @user = FactoryBot.create(:user)
    @post_name = Faker::Lorem.sentence
  end
  context '写真テキスト投稿ができるとき'do
    it 'ログインしたユーザーは新規投稿できる' do
      # トップページに移動する
      visit root_path
      # トップページにログインページへ遷移するボタンがあることを確認する
      expect(page).to have_content('LOGIN')
      # ログインページへ遷移する
      visit new_user_session_path
      # 正しいユーザー情報を入力する
      fill_in 'Eメール', with: @user.email
      fill_in 'パスワード', with: @user.password
      # ログインボタンを押す
      find('input[name="commit"]').click
      # トップページへ遷移することを確認する
      expect(current_path).to eq(root_path)
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 新規投稿ページへのリンクがあることを確認する
      expect(page).to have_content('PUSH 投稿')
      # 投稿ページに移動する
      visit new_post_path
      # 添付する画像を定義する
      image_path = Rails.root.join('public/test_image.png')
      # フォームに情報を入力する
      attach_file('post[images][]', image_path, make_visible: true)
      fill_in 'post[name]', with: @post_name
      # 送信するとPostモデルのカウントが1上がることを確認する
      expect{
        find('input[name="commit"]').click
      }.to change { Post.count }.by(1)
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 写真投稿一覧ページには先ほど投稿した内容の写真テキストが存在することを確認する(画像)
      expect(page).to have_selector("img[src$='test_image.png']")
      # 写真投稿一覧ぺージには先ほど投稿した内容の写真テキストが存在することを確認する(テキスト)
      expect(page).to have_content(@post_name)
    end
  end
  context '写真投稿ができないとき'do
    it 'ログインしていないと新規投稿ページに遷移できない' do
      # 写真投稿一覧ページに移動する
      visit posts_path
      # 新規投稿ページへのリンクがない
      expect(page).to have_no_content('nPUSH 投稿')
    end
  end
end

画像挿入するだけのことでしたがかなり時間を使ってしまいました。

冷静に頭を整理して、根本のところから他に定義するメソットはないのという発想で成功することができました。

もし似たような内容で詰まっている方などいましたら、ご参考にして頂けましたら幸いです。

宜しくお願いします!!

0
0
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
0