Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails4 - testing confused..needs recommendation

I am relatively new in TDD for rails. I have started working on a project, where I would want to make sure my code does what it is expected to do (in backend as well as in front-end)

I see rails officially does have its own tests framework (model level, controller level and integration level as mentioned at http://guides.rubyonrails.org/testing.html ), if so, then what is the use of these: rspec, cucumber, factorygirl, capybara, etc.) and why to use them rather than rails own testing framework?

My goal of asking this question is to find out what would I miss if I use rails own testing approach? and in that case, what should I pick from the above list to make my code completely tested?

My ultimate goal is (in order):

1) Write model - test does it work as expected?
2) Write controller - does it apply business logics as expected?
3) Front end : do templates get rendered as expected
4) As a user scenario: Does my webpage works as expected on user actions (in logged in or non-logged in scenarios). (For example, if I click sort link, then does data get sorted (using ajax). When user hover a div, it changes color to black etc.)
5) Now I want to deploy my code on heroku/aws/engineyard etc., so I want to run a complete tests (smoke tests, integration testing?), before code gets deployed.

So as per my above steps order, does rails native test framework work?

I am the only developer and product manager/designer of this project, so all these are for me, not for any third party.

like image 872
JVK Avatar asked Oct 02 '22 16:10

JVK


1 Answers

Unit Testing

By default Rails uses test/unit (now minitest) in its built in tests. This is a part of the ruby standard library and has the advantages of being lightweight and not needing further dependencies.

Rspec is an alternative to test/unit that is very full-featured and uses different language to try to help drive the BDD/TDD process. A comparision example:

# minitest
def test_new_users_should_be_active
  user = User.new
  assert_equal true, user.active?
end

# rspec
describe User do
  it 'should be active' do
    User.new.active?.should be true
  end
end

Both of these could be written various ways in either framework but hopefully this helps to give you a sense of the flavor of their differences. Here is some more discussion on the differences between minitest & rspec.

Factories

Factory_girl is a library which can be used with either rspec or minitest to create factory objects to simplify tests which have more complex setup. Here is some discussion about why you might want to use a factory library instead of fixtures (which are built into rails testing by default).

End to end testing

Capybara & webrat are two libraries which stack on top of either minitest or rspec and allow you to do integration testing. So these allow you to run tests against your full application operating through a browser so you can do things like fill in forms, click on links and verify that end-to-end what you are expecting is actually happening.

These kinds of integration tests tend to be much slower than unit tests but can be very helpful for verifying critical paths in your application. Capybara is now more regularly maintained and is what I would suggest for this kind of testing.

Acceptance Testing

Cucumber sits on top of any of these tools and lets you write tests in plain english which are then translated via a DSL to repeatable steps which run your actual tests. This is particularly helpful when you have a client or project manager who doesn't code or you want to be able to communicate requirements easily in english.

If this project is just you, I'd probably skip this one for now.

Continuous Integration

You can either run your tests manually whenever you want or use a continuous integration service to automatically run your tests for you. There are several good ones:

  • Travis CI
  • Circle CI
  • Drone.io

I have a lot of experience with Travis but have heard good things about the others as well. If you want to run your own CI server, Jenkins is a good option.

Breaking it down

Let's apply these to your specific examples of types of tests you want to write:

Use minitest (tests built-in) or rspec for

  • Write model - test does it work as expected?
  • Write controller - does it apply business logics as expected?
  • Front end : do templates get rendered as expected

Rails calls model tests unit tests and controller tests functional tests, but they are actually both types of unit tests.

Testing your views can be accomplished by using assertions on body produced in your controller tests (example). Rspec breaks out view tests into their own type.

Use capybara for

  • As a user scenario: Does my webpage works as expected on user actions (in logged in or non-logged in scenarios). (For example, if I click sort link, then does data get sorted (using ajax). When user hover a div, it changes color to black etc.)

Run manually or (better) use a continuous integration service for

  • Now I want to deploy my code on heroku/aws/engineyard etc., so I want to run a complete tests (smoke tests, integration testing?), before code gets deployed.

More resources

  • Rails Guide: testing rails
  • Poltergeist - a capybara driver which uses PhantomJS to run headlessly
like image 173
Matt Sanders Avatar answered Oct 19 '22 05:10

Matt Sanders