Why does my Cucumber test fail when run with Selenium? - ruby-on-rails

I am testing a Rails 3 app with a Cucumber/Capybara combo. I am also trying to use Selenium to test some JavaScript specific scenarios but am running into weird difficulties I don't understand.
My experience with Cucumber/Capybara is pretty low, my experience with Selenium is zero.
Here's the scenario:
Scenario: Browsing events
Given many events exist
And I am on the events page
Then I should see a list of 15 events
When I follow the first event
Then I should be on the event page
And I should see a google map
And I should see the event details
When that scenario runs under RackTest, it passes all the way up to the Google Map step, at which point it fails because there's no JavaScript. This is expected.
When I run the test with the default JavaScript driver (Selenium) it fails on step three (I should see a list of 15 events). When I observe the browser window, indeed the list of events contains no events at all - almost as if they don't exist in the database.
Incidentally, the first step (many events exist), uses FactoryGirl to create a load of events.
As this is all pretty new to me, I wonder if I'm being caught out by a typical gotcha? I haven't made any configuration changes other than the standard install from rails g cucumber:install. Also, if it's relevant, I'm using OSX.
Thanks

I presume you are trying to use transactional fixtures (the default behavior) with Selenium, but that won't work. The transaction that is managed within the test is out of scope when the browser invokes the Rails app separately, so it can't see any of the uncommitted data that your test has created.
Instead of transactional fixtures, you'll need to use one of the database cleaner gems.
https://github.com/bmabey/database_cleaner
Edit:
I subsequently became aware that it is possible to use transactional fixtures with Selenium tests, and performance is better if you do (credit to Kira Corina's answer). See http://pastie.org/1745020 for details.

For those who have the same issue with database in selenium tests, here is a really useful chat with three basic solutions summarized by Jonas (see the first April, 5th message):
https://groups.google.com/forum/#!msg/ruby-capybara/JI6JrirL9gM/R6YiXj4gi_UJ

Related

how to examine contents of database during or after rails integration test

I'm a fairly experienced dev but I'm a total web and rails newbie. I'm trying to implement a kind of market place rails application. I've developed the app to where I'm far along in the customer interaction flow and now I'm realizing I need to automate stuff cause dev/test via browser consumes so much time.
Say I have customer interaction flow that goes from page A, then to page B, C, D...G. And now I'm developing the 'H' page. I know I could use the automated test facilities (e.g. Minitest) to automate the whole thing. But being as how I still have my rails training wheels on sometimes I like to see database state progress from one state to the next for myself rather than just trust that the test automation really is doing what I'm expecting.
My question is, is there a way to have Minitest automate/simulate the user interaction flow from A -> G and then let me take over in a manual way from there such that I could click my newly-developed browser button while using my db browser to watch db state progress appropriately?
If not - which is what I'm guessing - I'd happily settle for a way to examine the database contents after an integration test. My integration tests work just fine. It's just that after they complete I'd like to be able to pop open my db browser and poke around, verifying various values to ensure to my satisfaction things in the db are as they should be.
Another possible solution that would work for me is if there was something within my integration tests that could access db values so I could verify things programmatically. I have in mind something like how assigns give you access to instance variables within your integration tests that you can then do 'asserts' calls on.
And, of course, please let me know if I'm way off track and there's a "best practice" for this type of thing that I've missed.
I'm using Rails 4.2.0 and Ruby 2.2.2p95
While Minitest doesn't have a way to do the first option you mentioned, you might checkout Watir as a means of (partially) automating tests so you leave off at a certain point with the browser still open and continue manually while watching what's going on in the DB.
However, since the second option you mentioned is possible with Minitest (and will save you even more time by being fully automated) I'd highly recommend it. See the Ruby on Rails Tutorial 3rd Edition by Michael Hartl for some examples (you might find the whole thing helpful, but here's a section that shows a test much like what you are looking for: Section 7.4.4.)

What's the fastest way to run integration tests against a rails app with significant database seeds?

I've got a ruby on rails application with significant database seeds that tie into the UI elements and are thusly required for integration tests.
I'm using database_cleaner to clean up after my tests, but due to the heavy js use of the application most of my tests can't be run with the transaction strategy which allows me to specify tables to leave out of the rollback.
The result is that I've got to re-seed the database before each test or deal with a dirty database. Does anyone have tips for testing in this kind of situation or know of any tools that may help?
Thanks!
I've dealt with this in the past by using transactions for our tests (we're using something a little homegrown for that at the moment but previously we used database cleaner).
The key is forcing everything to use the same database connection. The path I've been down for this is to set the database pool size in test to 1: everyone has to share the same connection because active record won't let you create more connections.
For this to work you need to be careful about releasing connections no longer in use, by calling ActiveRecord::Base.clear_active_connections!
There are 2 places you need to do this
when your test code is about to call visit, click etc.
after each request (use a Rack middleware for this- you can basically copy ActiveRecord::ConnectionAdapters::ConnectionManagement)
This works for us writing specs against pages that use ajax to fetch intermediate data and so on, but can be a bit tricky to get working initially. I wrote about it more extensively a while back

How would I test this view?

So I'm writing my app doing feature-first BDD with Rails, Cucumber, RSpec.
My client requested that a total gets calculated as you fill in the fields.
My question is, this is not really a feature, more of a spec. This is related to the feature of creating the invoice, but I don't think it justifies a whole integration test.
It's just javascript that's running.
So my mind is telling me to write a spec for this in the view spec. Is this correct? And is it possible to test these javascript cases in rspec?
Or should I isolate this a step further and go straight for a javascript testing framework?
I'd really recommend you start with integration tests for every feature you plan to add to your app, they're an invaluable tool for understanding the problem your trying to solve and communicating new additions to the software with clients.
To test JavaScript on your page, you may want to look into Selenium, from memory you can use Selenium as a drop in replacement of Rack::Test when using Capybara to test web pages.
As far as Cucumber goes, I'd suggest making a new feature file for creating the invoice and having a scenario that tests that the correct total total gets calculated when you enter a certain string into a field. Something like:
Scenario: Filling out the form
Given I am looking at the invoice form
When I fill in the fields with <value1> and <value2> without submitting
Then I should see <total> on the page
Obviously I don't know enough about your form to know what fields need to be filled out, but that's a general outline of how I'd test it. I'd also make a test in the view spec to ensure that there is a section for the calculated total value in the form.
After that, I'd drop down to writing specs for the Javascript in Jasmine and implement the code to calculate and display the total.
If you're just trying to test your JavaScript code, I recommend Jasmine.

Cucumber #javascript Breaks Oracle SQL Calls

I am using Ruby on Rails 3.0.7 Cucumber 1.0.1, and Oracle as the database. I have my own local user/schema for my development database, but I also connect to another Oracle database in a read-only fashion. Someone as my work has created a gem that allows me to talk to that other database and access its models. Let's say we call that other database Servo. Then I am able to do something like Servo::ModelName.all and all other regular calls.
The Oracle that gets generated by that is something like: SELECT * FROM "SERVO"."MODELNAMES"; Note that it appends the SERVO database name.
Now, I am writing a Cucumber test that at times, in my custom steps, uses Servo. That all works fine. The new scenario I am writing uses the #javascript tag. If any step (in the Background or in the Scenario) does not use Servo, then it runs fine. However, if I do use Servo, it breaks. The Oracle SQL being generated is suddenly SELECT * FROM "MODELNAMES"; and it is no longer aware of the other database.
So, any ideas why this is happening? Why does the #javascript suddenly change the SQL being generated? I couldn't find any good documentation about what else it does besides launching Firefox.
I'm sure others may want to know more information but I didn't want to flood this question so just let me know if you want some more details.
The main difference #javascript will introduce on the application side is that you're running a web server instead of routing requests directly through rack. I'd investigate with that knowledge and see if there isn't something you're doing in an initializer or something which could be affected by the different context.

Changing the value of a session variable in specs while testing in Ruby on rails.(with capybara and selenium)

I'm currently writing specs for my Ruby on Rails application using Rspec and capybara with selenium to drive the browser.
While executing one of the specs I want to change the value of a session variable.
Eg: I want to set session[:location]="US" so that I can test my application while all values are seen in $. How do I go about it?
Capybara/Selenium specs are for acceptance testing. You shouldn't do any kind of mocking, stubbing or...changing session values directly. You should interact with your application from within the spec just like a normal user would do in the browser.
How the location is being set in your app? Can the user set it manually? If yes, you should do it in the spec in a before block.
It's not exacly as you say.In Cucumber scenario we have chance to test some cases, and you must have a changes to create some background for that cases like create some user in Given block or add somethink to db and etc. Sessions is the same resoures like db and i thnik you should have the chance to prepare it for tests. No metter how strong it's connected with end-user.
Imagin that you create some multistep application where you presist some info beatween steps in session. Your client couldn't even imagin his reservation wihout any of this few steps. So from this point of few it's seems to not make any seans to create acceptance test for every step separatly. But after moth your client want's add some extra super user-frandly validation on 4th step. Now he is only intresting in this side and this validation. Probably he could deal with other extra 4th steps but why? He already saw all this staff and accept it.
What you think about this point of view?

Resources