0
votes

I can't manage to make my test suite work. I've tried to mix and match different configurations. But the results are all the same for this view: either nothing gets cleaned between tests or either the database is empty.

I get this kind of errors :

When nothing is cleaned

1) Authentication Sign in page as new user with valid information creates a user
     Failure/Error: select group.name, from: 'user_group_id'
     Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching option "Group g"

or this, an empty DB :

 1) Authentication Sign in page as new user with valid information creates a user
     Failure/Error: select group.name, from: 'user_group_id'
     Capybara::ElementNotFound:
       Unable to find option "Group g"

I've tried with and without database_cleaner.I've tried without Spork. I've tried different configurations form different sources, for exemple:

http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/

https://github.com/bmabey/database_cleaner#rspec-example

But I can't figure how to make it work.

Here's the Gemfile, with gems versions:

gem 'rails', '3.2.13'
gem 'sqlite3'

group :development, :test do
  gem 'libnotify'
  gem 'rb-inotify'
  gem 'rspec-rails'       (2.13.0)
  gem 'guard-rspec'       (2.5.1)
  gem 'guard-spork'       (1.5.0)
  gem 'guard-livereload'   
  gem 'rack-livereload'    
end

group :test do
  gem 'capybara'          (2.0.2)
  gem 'launchy'             
  gem 'database_cleaner'  (0.9.1)
  gem 'factory_girl_rails'
end

Here's the view:

<%= form_for(@user, url: sessions_path ) do |f| %>

  <div class="field">
    <%= f.label :group_id %><br />
    <%= f.collection_select :group_id, Group.order('name asc').all, :id, :name, :prompt => "Choose your Group" %>
  </div>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :phone %><br />
    <%= f.text_field :phone %>
  </div>
  <div class="actions">
    <%= f.submit 'Go !'%>
  </div>
<% end %>

The two Models :

class Group < ActiveRecord::Base
  has_many :users
  attr_accessible :name, :phone, :active
end




class User < ActiveRecord::Base
  belongs_to :group
  attr_accessible :name, :phone, :group_id

  validates_presence_of :name, :phone, :group
end

And the corresponding spec

require 'spec_helper'

describe "Authentication" do

  subject { page }
  before { visit root_path }

  describe "Sign in page" do
    let(:submit) {'Go !'}
    let(:session_new_content) { "Who's nearby"}
    let(:session_show_content){ "session show"}

    describe "as new user" do      
      describe "with valid information" do
        group = Group.create(name: "Group g")

        before do
          select group.name, from: 'user_group_id'
          fill_in 'Name', with: 'Samy'
          fill_in 'Phone', with: '0642604568'
        end

        it "creates a user" do
          expect{ click_button submit }.to change(User, :count).by(1)
        end

        describe "after saving the user" do 
          let(:user) { User.find_by_phone '0643614864'}  
          before do
            click_button submit
          end
          it { should have_content session_show_content}
          it { should have_content user.name}
        end
      end
    end
  end
end

Here's my spec_helper.rb

require 'rubygems'
require 'spork'


Spork.prefork do

  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|



    config.use_transactional_fixtures = false

    config.infer_base_class_for_anonymous_controllers = false

    config.order = "random"
    config.include Rails.application.routes.url_helpers

    config.include Capybara::DSL

    config.before(:suite) do
      DatabaseCleaner.strategy = :transaction
      DatabaseCleaner.clean_with(:truncation)
    end

    config.before(:each) do
      DatabaseCleaner.start
    end

    config.after(:each) do
      DatabaseCleaner.clean
    end
  end

end

Spork.each_run do
  FactoryGirl.reload
end

That's it any suggestions ?

1

1 Answers

1
votes

The issue appears to be here:

describe "as new user" do      
  describe "with valid information" do
    group = Group.create(name: "Group g")

    before do

You are creating a group outside of the before block, so it is created when the file loads (outside of a transaction).

In order to get everything to be happy, you need to move the group = Group.create(name: "Group g") call either inside a before block or inside the it block.

Edit: Or use a let helper such as let(:group) { Group.create(name: "Group g") }