Does your Rails code suffer from bloat, brittleness, or inaccuracy? Cure these problems with a regular dose of test-driven development. Rails 4 Test Prescriptions is a comprehensive guide to how tests can help you design and write better Rails applications. In this completely revised edition, you’ll learn why testing works and how to test effectively using Rails 4, Minitest 5, and RSpec 3, as well as popular testing libraries such as factory_girl and Cucumber. Do what the doctor ordered to make your applications feel all better. Side effects may include better code, fewer bugs, and happier developers.
Rails 4 Test Prescriptions: Build a Healthy Codebase
by Noel Rappin
Rails 4 Test Prescriptions
Build a Healthy Codebase
by Noel Rappin
Rails 4 Test Prescriptions is quite simply the best book on the market on the topic of testing Rails applications. It’s full of distilled wisdom from Noel’s many years of experience. I especially love the emphasis on thinking through the tradeoffs involved in picking a test strategy; in my experience, thinking intentionally about those tradeoffs is one of the most important steps you can take toward building an effective test suite.
- Myron Marston
Lead maintainer of RSpec and creator of the VCR gem
Rails 4 Test Prescriptions will benefit both developers new to test-driven development and those who are more experienced with it. Noel Rappin presents concepts like mocking and stubbing in a very detailed but also approachable and entertaining way. I loved the first edition of this book, and the second is even better. I highly recommend it!
- Nell Shamrell-Harrington
Senior developer, PhishMe
If anyone asks me how to master testing in Rails applications, I will tell them to read this book first.
- Avdi Grimm
Head chef, RubyTapas
Sometimes testing sucks. This book magically makes testing not suck; it makes it easy and rewarding with well-written explanations. It is the essential resource for any developer testing Rails applications. It’s more than just a testing primer; developers will learn how to create optimal and efficient test suites for Rails. A must-read for beginners and seasoned programmers alike.
- Liz Abinante
Software engineer, New Relic
About this Title
Release: P1.0 (2014-12-10)
Your Ruby on Rails application is sick. Deadlines are looming, but every time you make the slightest change to the code, something else breaks. Nobody remembers what that tricky piece of code was supposed to do, and nobody can tell what it actually does. Plus, it has bugs. You need test-driven development, a process for improving the design, maintainability, and long-term viability of software.
Containing both practical code examples and discussion of why testing works, this book starts with the most basic features delivered as part of core Ruby on Rails. Once you’ve integrated those features into your coding practice, you’ll learn how to use popular third-party testing tools such as RSpec, Mocha, Cucumber, and factory_girl. You’ll test the component parts of a Rails application, including the back-end model logic and the front-end display logic. Using Rails examples, you’ll learn how to use testing to enable your code to respond better to future change. Plus, you’ll see how to handle real-world testing situations.
Three RSpec 3 Features You Should Try
RSpec 3 is a major upgrade. In addition to solidifying changes in RSpec’s syntax and internals, it also added a number of new features. With these new features, you can specify the behavior of your application more flexibly and more exactly then before. Here are three new features of RSpec 3 or 3.1 that can make your tests more clear and precise.
For much more information on how to use RSpec in the context of test-driven development of a Rails application, read Rails 4 Test Prescriptions!
1. verifying doubles
A typical RSpec test double (sometimes called a mock object) is used to stand in for a real object in your system. However, the double does not know anything about the object it is replacing. This leads to a common problem where you specify that a double should respond to a method that is not actually defined in the code. As a result, the test passes, but the code calling that non-existent method fails when the code is executed outside the test.
Verifying doubles solves this problem by allowing you to give RSpec a little bit of information about the object being replaced so that RSpec can fail the test if an undefined method is called. With the configuration option `verify_partial_doubles` set, then any double you set on an existing object will validate that the object responds to the message. For example, if you say `allow(user).to recieve(:name).and_return(“Fred”)` then the verifying double will cause the test to fail if `User#name` is not defined.
You can also create verifying doubles that are not extensions of existing instances by using variants of the RSpec `double` method. These extensions include `instance_double(“User”)` and `object_double(User.new)`. In both cases, the resulting double will insist that any message expectation sent to it be already defined -in this case, already defined in the `User` class.
2. The `have_attributes` matcher
Ever written a spec that ended like this:
`expect(user.name).to eq(“Noel Rappin”)` `expect(user.height).to eq(140)` `expect(user.handedness).to eq(“left”)`
It’s dreary and becomes hard to read.
RSpec’s `have_attributes` matcher to the rescue.
`expect(user).to have_attributes(name: “Noel Rappin”, height: 140, handedness: “left”)`
You’ll get a nice error message telling you which attribute or attributes don’t match.
3. Compound Matchers
RSpec 3 allows you to chain matchers using the `and` method to chain two matchers that both must pass, and the `or` method to chain two matchers where only one needs to pass.
For example, let’s say you were checking that an inputted value had a couple of different characteristics. You might have in the past have done this:
`expect(name).to start_with(“Noel”)` `expect(name).to end_with(“Rappin”)`
In RSpec 3, you can also express the same expectation with `and`:
`expect(name).to start_with(“Noel”).and end_with(“Rappin”)`
If only one of those expectations needs to be true, which would be somewhat awkward to express before RSpec 3, use `or`:
`expect(name).to start_with(“Noel”).or end_with(“Rappin”)`
What You Need
Ruby 2.1, Rails 4
Contents & Extracts
- A Testing Fable
- Who You Are
- The Power of Testing First
- What Is TDD Good For?
- When TDD Needs Some Help
- Words to Live By
- A Word About Tools, Best Practices, and Teaching TDD
- Coming Up Next
- Changes for the Second Edition
- Test-Driven Development Basics excerpt
- The Requirements
- Where to Start?
- Running Our test
- Passing Our Test
- The Second Test
- Our First Date
- Using the Time Data
- What We’ve Done
- Test-Driven Rails
- And Now, Let’s Write Some Rails
- The Days Are Action Packed
- Who Controls the Controller?
- A Test With A View
- What Have We Done? And What’s Next?
- What Makes Great Tests
- The Big One
- The Big Two
- The More Detailed Five: SWIFT Tests
- Testing Models
- What Can We Do In A Model Test?
- What Should I Test in a Model Test?
- Okay, Funny Man, What Makes a Good Set of Model Tests?
- Refactoring Models
- A Note on Assertions Per Test
- Testing What Rails Gives You
- Testing ActiveRecord Finders
- Modeling Data
- Adding Data To Tests
- What’s the Problem?
- Dates and Times
- Using Mock Objects
- Mock Objects Defined
- Installing Mocha
- Creating Stubs in Mocha
- Mock Expectations
- Using Mocks To Simulate Rails Save
- Using Mocks To Specify Behavior
- More Expectation Annotations
- Mock Tips
- Coming Up Next
- Testing Controllers And Views excerpt
- Testing Controllers
- Simulating Requests in a Controller Test
- Evaluating Controller Results
- Testing Routes
- View Tests
- Testing Helper Methods
- Testing View Markup
- Testing Mailers
- Managing Controller and View Tests
- Driving Behavior With RSpec
- Getting Started With RSpec
- RSpec in 10 Minutes
- The “It” Factor
- Great “Expect”ations
- Mocking RSpec
- Let RSpec Eat Cake
- RSpec On Rails
- RSpec and Models
- Controllers in RSpec
- RSpec and Views
- RSpec Routing Tests
- RSpec and Helpers
- Write Your Own RSpec Matchers
- RSpec and Sharing
- Data About Metadata
- What’s Next
- Integration Testing with Capybara and Cucumber
- What to Test in an Integration Test
- Setting up Capybara
- Outside in Testing
- Using Capybara
- Making the Capybara Test Pass
- Setting Up Cucumber
- Writing Cucumber Features
- Writing Cucumber Steps
- More Advanced Cucumber
- Is Cucumber Worth It?
- Looking Ahead
- Testing External Services
- Testing For Security
- User Authentication and Authorization
- Troubleshooting and Debugging
- Improving Your Test Environment
- Running Smaller Groups of Tests
- Making Faster Tests
- Testing Legacy Code
Noel Rappin is a senior developer and director of talent at Table XI, and the author of multiple technical books. Before joining Table XI, Noel ran internal training at Groupon, and has a Ph.D. in educational technology and user-centered design from the GVU Lab at the Georgia Institute of Technology. Find Noel online at noelrappin.com.
Upcoming Author Events
High Cost Tests and High Value Tests: There is a value in writing tests and there is also a cost. The currency is time. The trade-offs are difficult to evaluate because the cost and value are often seen by different people (RubyConf, New Orleans)