Cucumber @javascript scenarios loose seeded data

I just started enabling @javascript on some cucumber scenarios and I am having some lack of understanding as to what is going on with data which should be seeded in the db:

In env.rb I have:

AfterConfiguration do |config| Factory.create(:sysadmin_role) Factory.create(:practice_admin_role) Factory.create(:practice_user_role) end

So that I have necessary roles to create users.

When a scenario with @javascript runs, I get the following error, which relates to the fact that the role that is being sought does not exist:

-10-07 20:22:29] ERROR RuntimeError: Called id for nil, which would mistakenly be 4 – if you really wanted the id of nil, use object_id /Users/DK/Documents/ror/projects/wavelineup3/app/controllers/practices_controller.rb:38:in `create’

And when I check on the db, my factories are not there, i.e. Role.all = .

I have tried everything including creating the data directly in the associated step itself and to no avail. Any advice? I am going to be doing a lot of ajax/js testing, should I ditch Capybara in favor of Selenium?

Thanks,

David

David Kahn wrote:

I just started enabling @javascript on some cucumber scenarios and I am having some lack of understanding as to what is going on with data which should be seeded in the db:

Nothing should ever be seeded in the DB in testing. You want a clean slate. Set up only the records you need for each scenario.

Best,

Nothing should ever be seeded in the DB in testing. You want a clean

slate. Set up only the records you need for each scenario.

Right - maybe I am missing something, how do you add records before a scenario? Is there a before(:each) like in rspec?

Also, I just changed my env.rb to culerity which I overlooked: Capybara.javascript_driver = :culerity #default driver when you using @javascript tag

I now see this error on a lot of tests - have you seen this? I did not exhaustively google but does not seem to be any clear and easy resolution: Broken pipe (Errno::EPIPE)

Thanks,

David

Nothing should ever be seeded in the DB in testing. You want a clean slate. Set up only the records you need for each scenario.

THIS

if you need your scenario to have some context use background: like this

Background: Given a thug exist with name: “juan”

And a car exist with owner: “jonny”

Scenario: can steal car Given “juan” is near the car When “juan” opens it Then I should not see the police

Scenario: get busted

Given “juan” stole the car

When “jonny” calls the police

Then I should see “juan” get arrested

this way jaun and jonny exist for both scenarios and the their are created for each feature. also i like using selenium-webdriver to test javascript if i see something wrong in the first pass.

David Kahn wrote:

Thanks Marnen and Radhames for the help… got things working. Radhames, took your lead and tried the selenium driver instead of culerity.

I think there is some issue with culerity on Rails 3/1.9.2 (a broken pipe error occurs regularly) but w selenium things went smooth. You probably already know this but for completeness of this post, I actually found while looking at Scenario Backgrounds the cucumber hooks for running something before each scenario in the whole suite (below)… in this case the user roles always have to be there so it makes more sense to put this there than inside each feature.

env.rb

Before do Factory.create(:sysadmin_role) Factory.create(:practice_admin_role) Factory.create(:practice_user_role) end

David Kahn wrote:

Thanks Marnen and Radhames for the help... got things working. Radhames, took your lead and tried the selenium driver instead of culerity.

I think there is some issue with culerity on Rails 3/1.9.2 (a broken pipe error occurs regularly) but w selenium things went smooth. You probably already know this but for completeness of this post, I actually found while looking at Scenario Backgrounds the cucumber hooks for running something before each scenario in the whole suite (below)... in this case the user roles always have to be there so it makes more sense to put this there than inside each feature.

No, no, no, it really doesn't. Do you actually touch all three of those roles for every single Cucumber scenario? (I'll bet you don't.) If you don't, then you're just making extra records and confusing what you're testing. The Before block is not the place to create records.

env.rb

Before do   Factory.create(:sysadmin_role)   Factory.create(:practice_admin_role)   Factory.create(:practice_user_role) end

Best,

No, no, no, it really doesn’t. Do you actually touch all three of those roles for every single Cucumber scenario? (I’ll bet you don’t.) If you don’t, then you’re just making extra records and confusing what you’re testing. The Before block is not the place to create records.

Its a grey area, as user roles a a presupposition of the system, and probably 90%+ of all tests would fail without them — and they are far from my mind when writing scenarios. I could put them instead in the step which creates any user, but that is less pretty as I might create several users throughout a single scenario. They are the only seed data that would go into the production database.

Originally I added them in env.rb using the following which would add them once: AfterConfiguration do |config| Factory.create(:sysadmin_role) Factory.create(:practice_admin_role) Factory.create(:practice_user_role) end

But with the @javascript tests they were not loading (or were getting deleted).

David Kahn wrote: [The following paragraph was me. Please quote properly.]

No, no, no, it really doesn't. Do you actually touch all three of those roles for every single Cucumber scenario? (I'll bet you don't.) If you don't, then you're just making extra records and confusing what you're testing. The Before block is not the place to create records.

[And back to you...]

Its a grey area, as user roles a a presupposition of the system, and probably 90%+ of all tests would fail without them --- and they are far from my mind when writing scenarios.

They should not be far from your mind! You should set them up in every test and scenario for which you need them, so that you know exactly which features depend on them.

I could put them instead in the step which creates any user, but that is less pretty as I might create several users throughout a single scenario.

That's OK. Create the users with appropriate roles as you need them (Pickle can really help here).

They are the only seed data that would go into the production database.

Fine, then seed the production database. Never seed the test database.

Originally I added them in env.rb using the following which would add them once: AfterConfiguration do |config|    Factory.create(:sysadmin_role)    Factory.create(:practice_admin_role)    Factory.create(:practice_user_role) end

I know. That's bad practice, as I've been explaining.

But with the @javascript tests they were not loading (or were getting deleted).

So take the time now to drop the bad practice and do it right!

Best,

They should not be far from your mind! You should set them up in every test and scenario for which you need them, so that you know exactly which features depend on them.

So take the time now to drop the bad practice and do it right!

I see the point and trying to swallow it. That’s going to make me think a bit differently but I can see the benefit. Although, this also makes me think that doing associations or the like within factories according to your logic would also be bad practice, right? I mean, that is also data which is implied.

David Kahn wrote:

They should not be far from your mind! You should set them up in every test and scenario for which you need them, so that you know exactly which features depend on them.

So take the time now to drop the bad practice and do it right!

[Still not quoting properly. That was me.]

I see the point and trying to swallow it. That's going to make me think a bit differently but I can see the benefit. Although, this also makes me think that doing associations or the like within factories according to your logic would also be bad practice, right?

No. Part of the reason we use factories is so we can produce, on the fly, a usable record with all associations and validations satisfied.

I mean, that is also data which is implied.

Huh? You mean in the sense that you didn't explicitly create the associated records? That's OK, because you're still creating them *for the particular test*.

See, your test DB should start out every scenario or test completely empty, and only create the records needed for that particular test. If (say) Factory :event also creates a User record for the Event to belong to, that's fine -- an Event (in this example) can't exist without an owning User, so we need the User in order to test the Event. We are creating all necessary records, but only the necessary records.

Best,

See, your test DB should start out every scenario or test completely

empty, and only create the records needed for that particular test. If (say) Factory :event also creates a User record for the Event to belong to, that’s fine – an Event (in this example) can’t exist without an owning User, so we need the User in order to test the Event. We are creating all necessary records, but only the necessary records.

Right, I fully agree with this. So either I should create the roles in this case before each test or let the factories create, either way there is a clean slate.

David Kahn wrote:

See, your test DB should start out every scenario or test completely empty, and only create the records needed for that particular test. If (say) Factory :event also creates a User record for the Event to belong to, that's fine -- an Event (in this example) can't exist without an owning User, so we need the User in order to test the Event. We are creating all necessary records, but only the necessary records.

For the third time: fix your quoting!

Right, I fully agree with this. So either I should create the roles in this case before each test or let the factories create, either way there is a clean slate.

But your Before block is not creating *only* the necessary records for each test. That's why you shouldn't be using it.

Best,