getting the most out of rails tests
DESCRIPTION
The different kinds of tests in Rails each have their advantages and disadvantages. But if you can find the right balance between these different types of tests in your app, you can have better test performance, and better test coverage. It'll be easier to improve your test performance later on. And you can use your tests to help you beat procrastination and get started building new features more quickly.TRANSCRIPT
Getting the mostout of Rails tests
Balanced tests
Integration testsand Unit tests
My story
Lots of unitsno integration
Lots of unitsno integrationthen...
Lots of integrationLots of units
Lots of unitsno integrationthen...
Lots of integrationLots of unitsthen...
?
The testing pyramid
» Use integration tests to test-drive your
features.
» Use unit tests to test specific objects,
models, modules, etc.
» Have many more unit tests than integration
tests.
Why balanced tests?
Faster test runs
(http://xkcd.com/303/, slightly edited)
Easier to improveperformance later
Easier to test-driveentire features
Less brittle tests
Better code coverage
A simpledevelopment process
Start with a sketch
Write a failingintegration test
require 'test_helper'
class CreateBugsTest < CapybaraTestCase test "can create a new bug" do visit bugs_path click_link "File new bug" assert_equal current_path, new_bug_path
fill_in "Title", with: "My new bug" fill_in "Description", with: "Short description." click_button "File bug" # ...and so on... endend
Our goalGet the first part of the test to pass
Write a failingcontroller test
test "should create bug" do assert_difference("Bug.count", 1) do post(:create, bug: { title: "My new bug", description: "Short description." }) end assert_redirected_to bug_path(assigns(:bug))end
Write some failing
unit tests
test "can create a bug" do bug = Bug.new(title: "My new bug", description: "This bug was just filed by a test.") assert bug.save, "Bug couldn't be saved: #{bug.errors.full_messages}"end
test "should not create a bug without a description" do skipend
test "should not create a bug without a title" do skipend
test "should not create a bug with too long of a title" do skipend
# ... and so on ...
test "can create a bug" do bug = Bug.new(title: "My new bug", description: "This bug was just filed by a test.") assert bug.save, "Bug couldn't be saved: #{bug.errors.full_messages}"end
# should not create a bug without a description# should not create a bug without a title# should not create a bug with too long of a title
# ... and so on ...
Make your units green,Make your controllers green
Repeat!
So, once again:1.Draw a sketch
2.Translate that sketch into a failing integration test
3.Get the first part of that test to pass3a. Write a failing controller test3b. Write some failing unit tests3c. Get the tests to pass3d. Repeat!
Aim for agood balance
Justin Weisshttp://[email protected]@justinweiss
http://www.justinweiss.com/book