Rails observers are not firing when running Capybara integration tests - ruby-on-rails

I'm using observers in my Rails app for notifications, activity feeds, etc. They keep my models and controllers clean, work great on the app side, and in any non-integration test (I've unit tested them extensively/successfully). But I can't for the life of me get them working in integration tests. I have the following in spec/support/observers.rb (as a sanity check. I'd ideally only enable them for feature tests if I can get them to work at all):
RSpec.configure do |config|
config.before do
ActiveRecord::Base.observers.enable :all
end
end
No matter what I do, I can't get my observers to fire off during my integration tests (which is exactly what I really want to use to ensure that everything is truly working).
Does anyone have any insight on this or have any clue as to why I could be experiencing this? I'm using Rails 5.0.0beta3, and the latest versions of rails-observers, rspec-rails and capybara (from github master branches).

This isn't truly an answer to my question, but ain't nobody got time to wait around. No one cares about observers anymore because they were removed form Rails 4. There are next to no google topics related to them and capybara.
So, in order move on and get integration test coverage on the code I need, I'm refactoring my code to use concerns that include callbacks. This eliminates the observer dependency, and I was actually able to abstract my code even further this way since many of my observers were doing pretty much the same thing, and I had the core of what my observers were calling in service objects anyway.
Integration tests have no problem triggering these.
RIP Observers.
https://stackoverflow.com/a/18581715/2202674

Related

Suspending Testing State w/Capybara Automation and FactoryGirl

This is maybe a bit of an odd question, i've googled around and haven't seen any questions asked (But maybe im asking the wrong question).
So i've been rewriting Integration tests using Factories (Which is interesting, and thanks to the fine people at this site for your help!). But im pretty much relying on screenshots to see that what im wanting to happen in the tests is happening.
Im using a Test database (SQlite to be specific), and since im using Factories the data gets deleted of course once the test is over, so it's like it never happened. So running a server using the test environment I can't really "manually" verify the data.
Is there a good way to be able to manually verify the data? Like stopping the test RIGHT at the end or pausing it temporarily? I suppose I could put in a gigantic sleep...but surely there is a better way?
But a breakpoint in your test, then use whatever commands you like to query the db.
I use gem 'pry-rails' in my Gemfile
then you simply put the line binding.pry in the test and it will freeze there in the terminal and you can check variables, make db calls like User.all or User.count and if you also add the gem pry-nav you can navigate with next, step, continue etc

How should I test my Rails app?

In the past couple of days I've been making slow progress adding tests to an existing rails app I've been working on for a little bit.
I'm just trying to figure out how much and what kind of tests (unit, functional, integration) will be enough to save me time debugging and fixing deploys that break existing functionality.
I'm the only one working on this application. It's basically an inventory management database for a small company (~20 employees). I didn't add testing from the beginning because I didn't really see the point but I've have a couple of deploys screw up existing functionality in the last little bit, so I thought it might be a good thing to add.
Do I need to test my models and controllers individually AND perform integration testing? There seem to be developers who believe that you should just integration test and backtrack to figure out what's wrong if you get an error from there.
So far I'm using RSpec + Factory Girl + Shoulda. That made it pretty easy to set up tests for the models.
I'm starting on the controllers now and am more than a little bit lost. I know how to test an individual controller but I don't know if I should just be testing application flow using integration tests as that would test the controllers at the same time.
I use integration tests to test the successful paths and general failure paths, but for the edge cases or more in-depth scenarios then I write model/view/controller tests.
I usually write the tests before writing the functionality in the application but if you want to add tests afterwards then I recommend using something like SimpleCov to see which areas of your application need more testing and slowly build up the test coverage for your application.
Writing tests after the app is already written is going to be tedious. At a minimum you should be testing for integration cases (which will test most controller functions and views), and also model tests separately so that your model calls work as you think they should.
For integration testing I find Capybara easy to use.
As a rule of thumb, most of your tests need to be unit, some functional, few integration.
Rails adheres to this wholeheartedly and you should do the same.
At the minimum you have to have:
A unit test for each of your models, add a test case for each of your validations in each of them, and finally a last one to make the sure the model is saved. If you have stuff like dependant: :destroy, touch: true on related models (has_many, belongs_to), add test cases for them as well.
A functional test for each of your controllers. Test cases for each action. Some actions can have multiple responses (like in case of 422 errors) so add another case to test the error response. If you have a authorization filter, test them as well.
Then you can have an integration test for a typical new user flow. Like
Sign Up -> Create Post -> View it -> logout. Another one is to make sure that unauthorized users cannot access your resources.
And from now, do not commit ANY code without the above mentioned tests.
The best time to plant a tree was 10 years ago, second best time is now, so start testing!

Recommended testing frameworks for Rails 2 app with randomness

I have a Rails 2.3.5 app which is serving a card game. I've been a bit lax in writing tests for it (read: I haven't written any :embarrassed:), and I'd like to make a start now.
From reading other questions, I think I probably want to be using Shoulda extending Test::Unit for unit testing.
I wondered about using Capybara extending RSpec for functional testing, but the majority of users' interaction with the app is via POST, which I understand Capybara doesn't handle.
Since this is a card game, I obviously need the ability to control rand; I also definitely need the framework to handle Javascript.
Is Test::Unit + Shoulda suitable?
Am I correct that Capybara can't handle POST? Can I work around that?
Is there a better option instead of Capybara?
Can these methods handle the randomness involved in a card-game? Presumably, for Test::Unit at least, I can just call srand at some early stage to fix the generator, but I don't know if that's doable for Capybara/RSpec/anything else.
Can anyone point me to resources dealing specifically with setting up Shoulda, Capybara and RSpec for Rails 2.3.5? It's a little hard to tell what's Rails 3 specific and what isn't.
Would I gain anything from adding Watir / Firewatir into the mix?
I realise the above questions are manifold, but they basically boil down to "does this work, or have you any better suggestions?"
If the majority of the users' interactions are via POST, is it via an API (as opposed to filling out forms or something)?
Just about any combination of RSpec/Shoulda/Capybara/Test Unit/Rack::Test could work for you depending on your need. They're all capable. However, these are my recommendations:
If you've decided you want integration testing via HTML pages, use Cucumber and Capybara
If you've decided you want integration testing via HTTP API, use RSpec and Rack::Test
You probably want to fake out randomness.
You probably don't need Watir/Firewatir.
It does look like you can make POST requests via some Capybara drivers:
http://suffix.be/blog/capybara-post-requests
When Rails moved to 3.0, RSpec went to 2.0 so for at least RSpec, you'd want RSpec and RSpec Rails 1.3.2.
By "fake out randomess", I mean redefine srand in your tests so you can predictably run them.
module Kernel
def rand
YourApp.rand
end
end
module MyApp
class << self
attr_accessor :rand
end
end
Then, before you have the user press the button, run a step definition like "When random returns 6", which will set MyApp.rand = 6.

Why does my Cucumber test fail when run with Selenium?

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

Rails Fixtures vs. Mocks

I'm developing a Rails app, and I was just talking with my colleague that we have a mix of fixtures and mocks in our tests, which we're doing using cucumber and Rspec. The question would be: when should each one be used?
I would use a mock object when using the real object is impracticable/not necessary. Lets say for example you need to call some remote API such as an address finder via zip code. You would probably want to mock the object so the calls on it aren't actually made each time you run your tests. There are other reasons too such as improving speed, asking for data that changes where you need an exact response or perhaps it doesn't exist yet. It allows you to test things in isolation as you can determine that when you call these methods on this mock object you will get this back and you don't actually need to run the code as for this test it's not important.
If you use fixtures you will have a real object and the methods etc will be called and their code run, unless of course you stub the methods out, which is something for another question.
Hope that helps a little. There is a good peepcode (http://peepcode.com/products/rspec-mocks-and-models) on mocking and stubbing, maybe check it out.

Resources