1

So, for some reason my routes increment by 11 when I run my comment feature test.

Exhibit A: I hit save on my comment_spec.rb

RSpec.feature "Adding comments to movies" do

before do 
@kyle = Admin.create(email: "kyle@example.com", password: "password")
@jill = Member.create(email: "jill@example.com", password: "password")


@movie = Movie.create!(title: "First movie", synopsis: "Synopsis of first  movie", year_released: '2000', admin: @kyle)
end

scenario "permits a signed in member to write a comment" do

login_as(@jill, scope: :member)

visit "/"

click_link @movie.title
fill_in "New Review", with: "An awesome movie"
click_button "Add Review"

expect(page).to have_content("Review has been created")
expect(page).to have_content("An awesome movie")
# must implement a nested route in order for this to work.
expect(current_path).to eq(movie_path(@movie.comments.last.id))
end

end

Then the test passes

moviesmoviesmovies/spec/features/comments_spec.rb:3)

Finished in 0.99879 seconds (files took 2.4 seconds to load) 1 example, 0 failures

Now, I hit enter in the terminal and get this:

Adding comments to movies permits a signed in member to write a comment
Failure/Error: expect(current_path).to eq(movie_path(@movie.comments.last.id))

expected: "/movies/2"
  got: "/movies/4"

(compared using ==)
# ./spec/features/comments_spec.rb:26:in `block (2 levels) in <top (required)>'

Then I save the comment_spec.rb again and get this:

Adding comments to movies permits a signed in member to write a comment
Failure/Error: expect(current_path).to eq(movie_path(@movie.comments.last.id))

   expected: "/movies/3"
        got: "/movies/15"

(compared using ==)
 # ./spec/features/comments_spec.rb:26:in `block (2 levels) in <top (required)>'

After this happens, I run:

bundle exec rails db:test:prepare

Then the tests pass again, but the above repeats. What in the world is making this happen? haha, but really?

My GitHub if needed.

winhowes
  • 7,845
  • 5
  • 28
  • 39
kyle
  • 207
  • 3
  • 17

1 Answers1

1

The issue you're having is that your database isn't being reset after each feature test, as you likely expect it is. Specifically, the problem is with Capybara and the config.use_transactional_fixtures = true line which is set in your spec config.

Capybara effectively tests your application as an external process using a virtual browser. This means that your capybara tests only have visibility into the client-side behavior of your app (i.e. the page variable). In other words, from Capybara's perspective your app is a "Black box". Therefore, capaybara doesn't see controller objects like your session, params, or request variables, nor can it see or control the specific database transactions which occur during testing.

Rather than relying on transactional fixtures, consider using database cleaner, which manually resets the database after each feature test. You can find the gem here: https://github.com/DatabaseCleaner/database_cleaner. Make sure you follow the directions on integrating with Capybara: https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example.

Anthony E
  • 11,072
  • 2
  • 24
  • 44
  • "Capybara effectively tests your application as an external process" – not exactly, it depends what driver you're using. With the default rack-test, it's within the same process. With Selenium, it's a separate process. – Andy Waite Apr 30 '16 at 10:13
  • True, I think anything other than RackTest runs a separate thread. In any case, Capybara tests themselves run in isolation from the controller. – Anthony E Apr 30 '16 at 10:18