You have a series of test cases. They cover the same logic with different inputs. In order to get to that logic, there’s some overhead: objects have to be created first. Then there’s more logic needed to evaluate the result. What’s the best way to manage these tests? You want it to be easy to add new tests. You also want it to be clear what part of the test is different in each round and what part is just the common logistics.
Previously on Locally Sourced: I wrote about building a small feature in Hotwire. Also, I have two, count ‘em, two, books for sale. Modern Front End Development For Rails (ebook) (amazon) and Modern CSS with Tailwind (ebook) (amazon). I have this idea that teams get in trouble when they do something that they are “supposed to do” without understanding what problem they are trying to solve and what tradeoffs they are willing to make to solve it.
Previously On Locally Sourced: The Entropy Essays are a series of essays about how programming practices inspired by Extreme Programming such as testing, pair programing, and object-oriented design play out on modern web projects. The first one was about test speed. And eventually we’ll get to why they are called Entropy Essays. I want you to stop for a second and think: “why are you writing this test?” Not “why are you writing tests in general?
Speed matters. But not precisely. There are only two things that matter when thinking about the speed of your automated tests: How fast can you run the relevant set of tests to let the tests be helpful in development? How fast can you run a complete, green build for deploy? We’re talking about the first one in this essay. In development, you want to be able to run the tests you are writing and a subset of tests that are most likely to break based on your changes.
For the first time in quite a while, I’ve been able to spend time working on a brand-new Rails application that’s actually a business thing and not a side project. It’s small. Okay, it’s really small. But at least for the moment it’s mine, mine, mine. (What was that about collective code ownership? I can’t hear you…) This seemed like a good time to reflect on the various Object-Oriented Rails discussions, including Avdi’s book, DCI in Rails, fast Rails tests, Objectify, DHH’s skepticism about the whole enterprise, and even my little contribution to the debate.
The key to fast tests is simple: don’t do slow things. Warning: this post is a kind of long examination of a problem, namely, how to integrate fast non-Rails tests and slow Rails tests in the same test suite. This may be a problem nobody is having. But having seen a sample of how this might work, I was compelled to try and make it work in my toy app. You’ve been warned, hope you like it.
As it happens, my generic advice on Rails testing hasn’t changed substantially, even though the tools I use on a daily basis have. Any testing tool is better than no testing. Okay, that’s glib. You can make an unholy mess in any tool. You can also write valuable tests in any tool. Focus on the valuable part. If you’ve never tested a Rails application before, I still recommend you start with out of the box stuff: Test::Unit, even fixtures.
Consider this part of an occasional series where I attempt to revisit tools discussed in Rails Test Prescriptions that have undergone some revision. (NOTE: Most of this was written before the DHH Twitter-storm about testing this week. For the purposes of this post, I’m choosing to pretend the whole thing didn’t happen.) The cucumber-rails gem released version 0.4 last week, which had some significant changes, and intensified what we might call the opinionated nature of Cucumber over what a Cucumber scenario should look like.
Book Status Beta 5 should be out early this week, featuring a mostly new chapter on testing legacy projects, and also updating the code setup and the initial walkthrough chapters to Rails 3. Over the next couple betas any remaining Rails 3 incompatibilities will also be fixed. Book Reviews Something new for you on a Monday, a couple of novels that I liked in the last couple of weeks. Kraken, by China Mieville.
And Now A Word The schedule for WindyCityRails 2010 just came out. WindyCityRails is Saturday, Sept, 11 at the Westin Chicago River North. I will be running the PM tutorial session on “Testing in a Legacy Environment”. I am frequently asked how to start testing on a pre-existing code base with no tests. In this session, we’ll start with a made-up “legacy” code base, and discuss techniques for adding tests, and fixing bug, and adding new features in a test-driven way.
Still catching up on links. The PeepOpen review has morphed into a larger IDE/TextMate piece, hoping to finish that today. Book Status Still working on the renovated Style chapter, which will probably combine the chapters that are in the current Table of Contents as “Testing Style and Structure”, “Fix Slow Tests”, “Rcov”, and “Help! My Test Is Failing”. The chapter on Legacy testing will remain a separate chapter – I get asked about how to test legacy projects all the time.
Book Status Starting to sound repetitive. Still working on the Cuke chapter, this time focusing on cleaning up the parts where I recommend ways to use Cucumber. Still hoping for a beta early next week. Other things This week in Yehuda, there’s a very long article about text encodings and what problems they have, and in particular how Ruby’s implementation is shaped by the complicated relationship between Unicode and Japanese.
Hey, where were you? Sorry about that, I spent most of last week running the Obtiva Ruby/Rails/TDD 4-day boot camp training, and I didn’t have time to do this daily catchup. Hey, if you think you need me or somebody like me to come to your company and blather about Ruby and Rails for a few days, contact us at http://www.obtiva.com. It’s fun. Book Status Rails test prescriptions: still on sale.
Top Story For me, the top story is still Rails Test Prescriptions on sale, and my discussion yesterday of the raffle for the old Lulu customers. Book Status Now re-doing the Cucumber chapter, which was written long enough ago that it didn’t consider tags. Cucumber has had approximately seventy-million releases in the interim, so there’s some writing to do. This is the first chapter where I’m adding Rails 3 setup instructions, which will eventually go everywhere in the book, of course.
Top Story If you think the top story is going to be anything other than the continued launch of Rails Test Prescriptions, well, you probably don’t know me very well. I may not be a marketing genius, but I do know the value of repetition. I mean, if there’s one thing I know, it’s the value of repetition. Thanks to everybody who made yesterday fun: those of you who bought the book, those of you who blogged or tweeted about the announcement, and anybody who read this.
Top Story For a while, it looked like the top story was going to be Apple’s new developer Rule 3.3.1, described here by John Gruber. More on that in a second. But the real top story is the news that Twitter has bought Tweetie, intending to rebrand it as Twitter for iPhone, and dropping the price to a low, low, free. Eventually, it will be the core of Twitter for iPad.
Here’s a little RSpec design question. As I’ve probably mentioned in various spots, I don’t naturally take to the RSpec massively-mocked style of testing. However, I’m currently on a Rails project that is using that style – unit tests don’t touch the database, functional tests don’t touch the models. It seems to be working for them, they certainly seem to have stuck with it over the course of this rather complex application.
First off, several pathfinder blog posts to catch up on… A two part series on a quick little testing tool that I wrote called testbed. Part 1. Part2. Predictions for 2008 How to test custom form builders in RSpec. I wrote this in the hope that somebody else won’t have to spend two hours Googling this. Coming soon, “Why I stopped using RSpec…” My contribution to a discussion on duck typing, Save the Duck!
Of all the exciting ideas and revelations that came from Kent Beck’s original XP book, Test-First Programming has been the one that most significantly affected the way I work on a day-to-day basis. I love programming test-first. It’s a great way to take a large, amorphous task and solve it piece by piece. It’s also a nice morale boost – “Hey, I know that my code does nine things. Let’s go for ten…”