expect(assigns(:clients)).to match_array(clients) fails or passes, very brittle behaviour

59 views
Skip to first unread message

Javix

unread,
Jul 9, 2014, 4:24:33 PM7/9/14
to rs...@googlegroups.com
I can't figure out why my example fails sometimes and sometimes not:

describe ClientsController do
  let(:admin) { create(:admin) }

  before(:each) { sign_in admin }

  describe 'GET #index' do
    Client.delete_all
    let!(:clients) { Array.new(3) { create(:client) } }
    it "populates an array of all clients" do

      get :index
      expect(assigns(:clients)).to match_array(clients)
    end

    it "renders the :index template" do
      get :index
      expect(response).to render_template :index
    end
   end
end

I set up DatabaseCleaner as follows in spec_helper:

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

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

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

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

and set up fixtures to false as well (spec_helper):

config.use_transactional_fixtures = false

No matter if I keep the line or not:

Client.delete_all

it fails the first time (when I run all the tests) and passes when I run the spec separately.

I also defined a shared_db_connection in support folder:

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection

For a more complete description of this setup, check out Avdi Grimm’s Virtuous Code blog:

Any idea? THANK YOU

Javix

unread,
Jul 9, 2014, 4:25:49 PM7/9/14
to rs...@googlegroups.com
P.S. I forgot to mention Rails and RSpec versions, sorry here are they:

Rails 4.0.3
rspes-rails 2.14.2

Myron Marston

unread,
Jul 11, 2014, 11:53:54 AM7/11/14
to rs...@googlegroups.com
The `Client.delete_all` line is problematic in that it runs at spec file load time, and many other examples can be run between that point and the examples you've listed run.  If any other examples create client records you're going to hit problems like you're seeing.  Instead, wrap it in a `before(:all)` hook if you want it to run once before all examples in that group.

That said, I question the need for it at all; your environment is setup to truncate the DB before the first example runs and then wrap each example in a transaction, so there shouldn't be any client records in the DB to be deleted...unless you have some records being put into the DB outside the scope of an example (e.g. in an example group body or a `before(:all)` hook).  And if you do have that kind of thing -- well, that's probably what's causing the problem.

HTH,
Myron

Serguei Cambour

unread,
Jul 12, 2014, 9:31:56 AM7/12/14
to rs...@googlegroups.com
Thank you Myron for the reply.
So I removed completely Client_delete_all statement as it is managed by DatabaseCleaner truncation feature.
And my features/ClientsPageSpec passes now.

Thank you.

--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/bwqHFUsldbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/99fcd847-9c68-4684-a396-4157d9412816%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Serguei Cambour

unread,
Jul 12, 2014, 4:15:42 PM7/12/14
to rs...@googlegroups.com
On 12 Jul 2014, at 15:31, Serguei Cambour <s.ca...@gmail.com> wrote:

On 11 Jul 2014, at 17:53, Myron Marston <myron....@gmail.com> wrote:

Thank you Myron for the reply.
So I removed completely Client_delete_all statement as it is managed by DatabaseCleaner truncation feature.
And my features/ClientsControllerPage


--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/bwqHFUsldbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/99fcd847-9c68-4684-a396-4157d9412816%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

WTF, it fails again...

Myron Marston

unread,
Jul 14, 2014, 2:05:15 PM7/14/14
to rs...@googlegroups.com
On Saturday, July 12, 2014 1:15:42 PM UTC-7, Javix wrote:
WTF, it fails again...

If you can put together a reproducible example, open an issue and we'll take a look.  It's hard (nearly impossible) for us to debug remotely based on the limited information you've given us.

Myron

Serguei Cambour

unread,
Jul 14, 2014, 2:22:38 PM7/14/14
to rs...@googlegroups.com
Tank you Myron.
Just for history, I was going to take a try with RSpec features (never used them before), instead of Cucumber's ones,  that’s why I was a little bit stuck with that. So I just deleted RSpec ‘features’ folder with all the specs inside and came back to Cucumber to be able to continue.
If I manage to check out a branch from the point where I had features available on my project, I’ll create a gist or even a branch and come back here with more details.
Thank you again for your fed back.

--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/bwqHFUsldbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.

Javix

unread,
Jul 15, 2014, 3:48:56 AM7/15/14
to rs...@googlegroups.com


On Wednesday, July 9, 2014 10:24:33 PM UTC+2, Javix wrote:
@Myron: I pushed to remote a branch that has RSpec features implemented. When running all the specs, tests failed (2). When running the same but separately, they pass.


Thank you. 

Myron Marston

unread,
Jul 15, 2014, 4:58:29 PM7/15/14
to rs...@googlegroups.com
Thanks.  I cloned it and tried to run your specs, but I'm getting 187 failures out of 190 specs.  They're all failing with errors like this:


I had to install postgres for this (I haven't used it in years) and I haven't used rails in years so I'm pretty rusty with debugging issues with this.  I also don't have much time to invest in this.  Sorry :(.

Maybe someone else can volunteer to take a look at your project?

Myron

 

Aaron Kromer

unread,
Jul 15, 2014, 11:06:32 PM7/15/14
to rs...@googlegroups.com

This is caused by your use of before(:all) blocks which create data in the database. If you are using the :transaction strategy, which it seems you are, then any data added in before(:all) is created prior to the transaction. This also means it’s left over after the example. I’m guessing you want to use the :all block for “performance reasons”. However, that may not be where your time is being spent. For example, your “Clients Page Has pagination and lists all clients” spec (spec/features/clients_page_spec.rb:24) took 13.25 seconds on my machine. That time was not spent creating the objects, but instead verifying everything on the page.

If you really must use before(:all) then you need to manually clean it up or change your configs. See the following references for more info:



--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.

To post to this group, send email to rs...@googlegroups.com.

Serguei Cambour

unread,
Jul 16, 2014, 2:16:53 AM7/16/14
to rs...@googlegroups.com
Not a problem, Myron.
For those who could take a look at the error, to set up the projet:
- have Postgresql installed
- run bundle install
- rake db:create
- rake db:migrate
- [optional] populate a database: rake db:populate (see lib/tasks/sample_data.rake for more details).
- rake db:test:prepare
- rspec

Thank you.

 

--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/17bb8aae-a3a6-4050-9b11-0f927145eb90%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/bwqHFUsldbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.

To post to this group, send email to rs...@googlegroups.com.

Myron Marston

unread,
Jul 16, 2014, 4:28:36 PM7/16/14
to rs...@googlegroups.com
On Tuesday, July 15, 2014 11:16:53 PM UTC-7, Javix wrote:
Thanks, I followed these steps and was able to run your specs. Not sure what I missed yesterday.  (Clearly it's been a long time since I worked on a rails app....).

Anyhow, Aaron's definitely right: the problem is that you have records that are being created in the DB outside of transaction and are "leaking" into other examples.  Any records created in the DB are essentially "global" state that has to be cleaned up between examples (or between example groups) and you're responsible for doing that.  With the database cleaner transaction strategy that you've hooked up for each example, it'll take care of that for any records created within an individual example but can't work for records created in the :all hooks.  I've created a PR that shows one solution for solving the problem:


Myron

Serguei Cambour

unread,
Jul 17, 2014, 2:02:15 AM7/17/14
to rs...@googlegroups.com
Thank you guys for your help, the links provided to learn more about DBCleaner, transaction, truncation rare reeeeeaaaally helpful (never had the need to dig it deeper :) ).
@Myron: I’ll integrate the PR in the nearest time (rush time for the moment).

THANKS A LOTS !!!!

--
You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/bwqHFUsldbg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages