mochi93kou
@mochi93kou (まるも)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

railsアプリでjp_prefectureを使い都道府県を選択するテストでエラー

解決したいこと

都道府県を選択しユーザーの登録をテストしたいです。

発生している問題・エラー

1) Users ユーザー新規登録 登録成功 仮登録画面へ遷移
     Failure/Error: select "東京都", from: 'user_address[prefecture]'
     
     Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching visible option "東京都" within #<Capybara::Node::Element tag="select" path="/HTML/BODY[1]/DIV[2]/DIV[1]/FORM[1]/DIV[3]/SELECT[1]">
     
     [Screenshot Image]: /Users/mochizukikouki/Documents/homepage/homepage_on_ruby_on_rails/homepage/tmp/screenshots/failures_r_spec_example_groups_users_nested_2_nested_仮登録画面へ遷移_688.png

     
     # ./spec/system/users_spec.rb:22:in `block (3 levels) in <top (required)>'

  2) Users ユーザー新規登録 登録失敗 名前が空欄
     Failure/Error: select "東京都", from: 'user_address[prefecture]'
     
     Capybara::Ambiguous:
       Ambiguous match, found 3 elements matching visible option "東京都" within #<Capybara::Node::Element tag="select" path="/HTML/BODY[1]/DIV[2]/DIV[1]/FORM[1]/DIV[3]/SELECT[1]">
     
     [Screenshot Image]: /Users/mochizukikouki/Documents/homepage/homepage_on_ruby_on_rails/homepage/tmp/screenshots/failures_r_spec_example_groups_users_nested_2_nested_2_名前が空欄_338.png

     
     # ./spec/system/users_spec.rb:22:in `block (3 levels) in <top (required)>'

  3) Users ユーザー新規登録 登録失敗 メールアドレスが空欄
     Failure/Error: select "東京都", from: 'user_address[prefecture]'
     
     Capybara::Ambiguous:
       Ambiguous match, found 4 elements matching visible option "東京都" within #<Capybara::Node::Element tag="select" path="/HTML/BODY[1]/DIV[2]/DIV[1]/FORM[1]/DIV[3]/SELECT[1]">
     
     [Screenshot Image]: /Users/mochizukikouki/Documents/homepage/homepage_on_ruby_on_rails/homepage/tmp/screenshots/failures_r_spec_example_groups_users_nested_2_nested_2_メールアドレスが空欄_748.png

     
     # ./spec/system/users_spec.rb:22:in `block (3 levels) in <top (required)>'

  4) Users ユーザー新規登録 登録失敗 パスワードが空欄
     Failure/Error: select "東京都", from: 'user_address[prefecture]'
     
     Capybara::Ambiguous:
       Ambiguous match, found 5 elements matching visible option "東京都" within #<Capybara::Node::Element tag="select" path="/HTML/BODY[1]/DIV[2]/DIV[1]/FORM[1]/DIV[3]/SELECT[1]">
     
     [Screenshot Image]: /Users/mochizukikouki/Documents/homepage/homepage_on_ruby_on_rails/homepage/tmp/screenshots/failures_r_spec_example_groups_users_nested_2_nested_2_パスワードが空欄_271.png

     
     # ./spec/system/users_spec.rb:22:in `block (3 levels) in <top (required)>'

Finished in 13.26 seconds (files took 0.84803 seconds to load)
11 examples, 4 failures

active_hashを使用してPrefectureモデルを擬似的に作っています。

class Prefecture < ActiveHash::Base
  field :name
  self.data = [
    {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
    {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
    {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
    {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
    {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
    {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
    {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
    {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
    {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
    {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
    {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
    {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
    {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
    {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
    {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
    {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
]
end

テストコード

require 'rails_helper'

RSpec.describe "Users", type: :system do
  
  describe 'ユーザー登録ページにアクセス' do
    it '正常に遷移する' do
      get new_user_path
      expect(response.status).to eq(200)
    end
  end

  describe 'ユーザー新規登録' do
    before do
      Prefecture.create!(name: "東京都")
      visit new_user_path
      fill_in 'user_address[name]', with: 'test' 
      fill_in 'user_address[email]', with: 'test@example.com' 
      fill_in 'user_address[password]', with: 'password' 
      fill_in 'user_address[password_confirmation]', with: 'password' 
      fill_in 'user_address[postcode]', with: '1111111'
      select "東京都", from: 'user_address[prefecture]'
      fill_in 'user_address[city]', with: '台東区'
      fill_in 'user_address[house_number]', with: '11-12'
    end
    
    context '登録成功' do
      before do
        ActionMailer::Base.deliveries.clear
      end
      
      it '仮登録画面へ遷移' do
        expect {
          find('input[name="commit"]').click
        }.to change{ User.count }.by(1)
        expect(ActionMailer::Base.deliveries.size).to eq(1)
        expect(current_path).to eq('/users/done')
        user = User.last
        expect(user.activated).not_to eq be_truty
      end
    end

    context '登録失敗' do
      it '名前が空欄' do
        fill_in 'user_address[name]', with: ''
        expect {
          find('input[name="commit"]').click
        }.to change{ User.count }.by(0)
        expect(current_path).to eq('/users')
      end

      it 'メールアドレスが空欄' do
        fill_in 'user_address[email]', with: ''
        expect {
          find('input[name="commit"]').click
        }.to change{ User.count }.by(0)
        expect(current_path).to eq('/users')
      end

      it 'パスワードが空欄' do
        fill_in 'user_address[password]', with: ''
        expect {
          find('input[name="commit"]').click
        }.to change{ User.count }.by(0)
        expect(current_path).to eq('/users')
      end
    end
  end
  
  describe 'ユーザー一覧へアクセス' do
    let!(:user) { create(:user) }
    let!(:admin) { create(:user, :admin_user) }
    
    context '管理者でログインしている' do
      it '正常に遷移する' do
        log_in_as(admin)
        visit users_path
        expect(current_path).to eq("/users")
      end
    end
    
    context '非管理者でログインしている' do
      it 'ログインページに遷移する' do
        log_in_as(user)
        visit users_path
        expect(current_path).to eq("/login")
      end
    end
    
    context 'ログインしてない' do
      it 'ログインページに遷移する' do
        visit user_path(user)
        expect(current_path).to eq("/login")
      end
    end
  end
  
  describe 'ユーザー詳細へアクセス' do
    let!(:user) { create(:user) }
    let!(:admin) { create(:user, :admin_user) }
    subject { log_in_as(user) }

    context '自分の詳細画面へアクセスした' do
      it '正常に遷移する' do
        subject
        visit user_path(user)
        expect(current_path).to eq("/users/#{user.id}")
      end
    end
    
    context '他ユーザーの詳細画面へアクセスした' do
      it 'トップページに遷移する' do
        subject
        visit user_path(admin)
        expect(current_path).to eq("/")
      end
    end

    context 'ログインしていない' do
      it 'トップページに遷移する' do
        visit user_path(user)
        expect(current_path).to eq("/login")
      end
    end
  end
end

view

<% provide(:title, "新規会員登録") %>
<script type="text/javascript" src="//jpostal-1006.appspot.com/jquery.jpostal.js"></script>
<div class="create-form">
  <div class="form">
    <div class="create-title">
      新規会員登録
    </div>
    <%= form_with(model: @user, url: users_path, local: true) do |f| %>

      <%= render 'shared/error_form', object: f.object %>

      <p class="form-required"><span>[必須]</span>は必須項目です</p>

      <div class="form-template">
        <%= f.label :お名前, class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:name) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:name).first %></div>
        <% end %>
        <%= f.text_field :name, class:"form-control", placeholder: "例:穂高 太郎" %>
      </div>

      <div class="form-template">
        <%= f.label :postcode, "郵便番号", class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:postcode) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:postcode).first %></div>
        <% end %>
        <%= f.text_field :postcode, class:"form-control", placeholder: "例:", id: "address_postcode", maxlength: "7" %>
      </div>

      <div class="form-template">
        <%= f.label :prefecture, "都道府県", class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:prefecture) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:prefecture).first %></div>
        <% end %>
        <%= f.collection_select :prefecture, Prefecture.all, :name, :name,{ class:"form-control", id: "address_prefecture", include_blank: true, selected: '' } %>
      </div>

      <div class="form-template">
        <%= f.label :city, "市区町村", class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:city) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:city).first %></div>
        <% end %>
        <%= f.text_field :city, class:"form-control", placeholder: "例:", id: "address_city" %>
      </div>

      <div class="form-template">
        <%= f.label :house_number, "町域・番地", class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:house_number) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:house_number).first %></div>
        <% end %>
        <%= f.text_field :house_number, class:"form-control", placeholder: "例:", id: "address_house_number" %>
      </div>

      <div class="form-template">
        <%= f.label :building, "建物名など", class:"form-label" %>
        <%= f.text_field :building, class:"form-control", placeholder: "例:", id: "address_building" %>
      </div>
      
      <div class="form-template">
        <%= f.label :メールアドレス, class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:email) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:email).first %></div>
        <% end %>
        <%= f.text_field :email, class:"form-control", placeholder: "例:hotaka@kyodo.com" %>
      </div>

      <div class="form-template">
        <%= f.label :パスワード, class:"form-label" %><p>[必須]</p>
        <% if @user.errors.include?(:password) %>
          <div class="form-alert"><%= @user.errors.full_messages_for(:password).first %></div>
        <% else %>
          <% if @user.errors.include?(:password_confirmation) %>
            <div class="form-alert"><%= @user.errors.full_messages_for(:password_confirmation).first %></div>
          <% end %>
        <% end %>
        <%= f.password_field :password, class:"form-control", placeholder: "6文字以上" %>
      </div>
    
      <div class="form-template">
        <%= f.label :パスワード(確認用), class:"form-label" %><p>[必須]</p>
        <%= f.password_field :password_confirmation, class:"form-control" %>
      </div>


      <div class="create_btn">
        <%= f.submit "登録", class:"btn btn-primary mb-3" %>
      </div>
    <% end %>
  </div>
</div>

0

1Answer

ユーザー新規登録テストの前処理でのPrefecture.create!(name: "東京都")がいらなそうです。
その処理を毎回するとPrefectureのHash内に「東京都」がテストケース分できて、一意にならないためエラーになっているのではないでしょうか

0Like

Comments

  1. @mochi93kou

    Questioner

    ありがとうございます!
    試したところ!
    エラー解決できました!

Your answer might help someone💌