-
Get a monthly update on best practices for delivering successful software.
edge case city: requirements and testing dates for HR business logic
We have an internal application that does staffing, time entry, and now Paid Time Off (PTO) accrual, scheduling and management. It is quite nice, as it has replaced three existing systems, and replaced a number of manual, tedious tasks. I started it last year, as our current system was very inefficient. It was a simple Ruby on Rails app that I was able to get working in a few weeks. Over time the functionality grew.
We recently added in PTO accrual and functionality to debit PTO time. In doing so in a test driven manner was great, as we could put all the edge cases. What we found was that many of the requirements were plentiful with edge cases. For instance, we get paid on the 15th or end of the month, unless that is a weekend. Then we get paid on a Friday - Except if that Friday is a holiday, then the previous Thursday - Except - if that is also a holiday.... So it is really the previous non-weekend, non-holiday on or before the 15th or end of the month. The same holds true to determine the beginning of the billing period. If the Monday is the 2nd, than for some operations the effective billing period start is Tuesday the third.... Ugh...
Our initial thoughts were filled with visions of lots of very similar tests for all contexts that do things depending on the start or end of a billing period. We didn't want to have lots of duplicate test code to test all edge cases, so we decided to extend the Date object to have a few helper methods to do the complicated logic in one place. We get the full range of the billing period start and end, and then trim off any holidays or weekends. What this did, was allow us to test the complicated logic in unit tests with a full set of complicated edge cases. We created many crazy examples of billing periods starting and ending on weekends, holidays, and holidays before and after weekends. This created a very robust set of methods to be used anywhere in the system.
We then mocked a call to each Date helper method everywhere in the system where it cared about what day it was, and weather it was the start/end of a billing period. We had only a few edge cases now: is it the true effective billing period start/end, or not. Our tests could then focus on the guts of what it actually did, regardless of the effective date.
This demonstrates how powerful unit testing is, and how mocking can really keep your tests concise. It made not only our code cleaner, but our tests cleaner. It reduced duplicate code, and increased our assurance that the code will function as designed.
That being said, it still doesn't change the fact that implementing HR logic in any language is a pain in the ass. I have worked on a couple of systems for accounting departments in the past, and their business requirements are much worse than HR. Dealing with job codes, general ledger accounts, etc can make your head spin. All I know, is that without TDD, this system would be buggy.

It's time to play "Ask A Tester Person", where I answer questions that I've gotten via email or otherwise about Rails Testing topics.
If you have a question for Ask A Tester Person, send it to railsprescriptions at gmail.com.
I've got two questions today:
Continue reading »
Topics: Ruby on Rails, tdd, Test Driven Development
Eric Smith from 8th light gave a hands-on TDD presentation at last night's Chiphone meeting, hosted at Obtiva's downtown office, (conveniently located near the the train).
There was a good crowd of people, most attendees have 'played around' with iphone development, 4 have actively developed apps (3 people have live apps in the store). From my quick survey of those that have submitted apps, it seems most of them were free utility apps or simple games, with at least one commercial app Dash for Confluence. It also seemed that no one had yet needed to do any animation beyond the basics, with just a bit of core-animation, but no need for more lower-level openGL or animation engines.
Eric started off by saying that he's given talks on iPhone testing, but that just telling people what to do is not the same as letting them experience it for themselves, so we did a Randori, where a pair starts working on some code, and every 3 minutes one person from the pair swaps out and chooses his replacement from the crowd.
What I liked about this was that I felt like I got to know the audience better, and actually watch people reason their way through the code or a testing/mocking issue. (You know how sometimes you go to a user group, and it can be hard to get a chance to talk to others, or sometimes there is a 'know-it-all' guy, and you just want him to shut up. Knowing that you are going to have to go up there and code is a great way to silence those types)
When it was my turn, there was an interesting issue with one of the tests that had us all stumped for a bit, but ultimately ended up being one of those problems where you need to deconstruct everything and build it back up. (The issue was that while we were trying to set fooController.textView.text = @"foobar", we hadn't instantiated a textView object, or set it on the controller yet.)
Continue reading »
So, I tried Blue Ridge for the first time yesterday and I thought I'd write down some quick impressions. Hence, Rails Testing First Look.
Disclaimer: We came into this tool so cold our toes froze. We fumbled, we made mistakes, we probably missed really great ways of doing things. I look forward to being enlightened.
Let's do this question-and-answer style: Continue reading »
Topics: rails testing, Ruby on Rails, tdd
Here's a minor thing that bugs me all the time.
I'm writing a functional test:
should "do something functional" get :search,rder_id => @order.id, :user_id => @user.id # and so on end
The get call in that test simulates a browser request. Intuitively, you would (well, I would) expect this request to be identical to a request coming from the actual view, via a helper like link_to("search", :action => :search, . At least, you'd expect that parameters hash in the controller to be the same between the
rder_id => @order.id, :user_id => @user.id)
Makes sense, right? The testing call should set up the same environment as the actual call being tested. Continue reading »
Topics: rails testing, Ruby on Rails, tdd, Test Driven Development, Testing, wapcaplet
Dot, dot, dot, dot, dot -- tests are passing, looks like it's time for lunch -- dot, dot, dot, dot, F. F? F? But the code works. I know it does. I think it does. Why is my test failing?
One of the most frustrating times as a TDD developer is that moment when a test is failing and you don't know why, as opposed to the more normal case where the test fails as expected. Here's a grab bag of tips, tricks, hints, and thoughts to get us all through that difficult time.
Topics: Ruby on Rails, tdd, Test, Test Driven Development, Testing
What with upward of two people saying nice things about last week’s post, I’ve decided to keep going with part two of a look at some real testing code.
Most code-heavy tutorials show the code but not the tests — I’m doing the opposite here, and showing the tests, but not much of the code. Also, although I’m presenting these tests in chunks, you should realize that there was a lot of back-and-forth from Cucumber to tests to code and some backtracking, most of which I’ll spare you from having to wade through.
At the end of last week, I had run through the tests for spam-prevention code which worked by limiting the rate at which a user could send messages to other users of a particular social networking site. Cucumber was involved, and I think I went off on a tangent about writing lots of tests.
Rails Prescriptions, the site and book by Pathfinder's Noel Rappin, got some nice words of praise from the official Rails weblog on Saturday:
Doing Test Driven Development (TDD) effectively is not something that comes easy, even when you’re working with a well structured Rails application. Up until March of this year there really was no guide I could recommend for developers who wanted to learn TDD with Rails.
What happened in March? Noel Rappin released his Rails Test Prescriptions PDF guide. You can start out by reading his FREE 84 page Getting Started With Rails Testing PDF Guide, and then maybe upgrade to his $9 dollar 286 page guide which covers advanced topics like creating Test helpers, stubbing, mocking, and even how to use factories, shoulda, rspec, and cucumber.
Check out the post, and the book.
Topics: Ruby on Rails, tdd, Testing

The ChicagoRuby users group (not to be confused with chirb.org another great Chicago Ruby user group) held their second meeting at their downtown location.
While the meetings out in Elmhurst are always informative and helpful, the downtown location may allow for a bigger crowd, and the weekday time might work better for more people. Plus, the Illinois Technology Association - Tech Nexus is right next to Union Station which works great for people that still have to go out to the suburbs.
Noel Rappin's talk covered some of the most common questions he gets through the Pathfinder Development Blog, and his own site RailsPrescriptions site RailsRX.com dedicated exclusivly to testing.
There's too much detail to cover here, but at a high-level, Noel covered:
The audience seemed to have a wide range of experience, but all had opinions to share about what they've learned about testing. After the talk everyone seemed fell into small groups to network and exchange ideas and contact info, and a group gathered around Ray and Noel as they tossed around some ideas on potential future meeting topics "Ruby IDE/Editor review", "Rails Jumpstart", "Coding Dojo".
The organizers took a stab at hosting the meeting virtually over gotomeeting (not sure if it was recorded or not).
Their next meeting is scheduled for July 18th, details can be found in their meetup.com group.

The organizers of the ChicagoRuby.com group are also the organizers of the 2nd annual WindyCityRails Conference right here in Chicago, on Sept, 12th, which Noel will be presenting at.
Topics: chicagoruby, chirb windycityrails, factory, fixturereplacement, fixtures, flexmock, mocking, rails, railsrx, rspec, ruby, shoulda, tdd, test::unit, Testing
My cucumber obsession continues unabated. I've spent a lot of the last week adding Cucumber to projects, writing about it in a very long section for the Rails Test Prescriptions book, and generally trying to figure out how to use this tool, not to mention trying to figure out why this tool has been so interesting to me this week.
Some follow-up thoughts since last week's post.
Continue reading »
Topics: Ruby on Rails, tdd, Test Driven Development, Testing
An consistent nuisance problem when testing Rails applications is the "unit test gap". This happens when the model test passes and the controller test passes, but the application as a whole fails because there's a mismatch between the output produced by the model and the input given to the controller test. In theory, Rails integration tests can solve this problem, but they aren't really designed for it, and nobody uses them much anyway.
An easy-to-use tool that solves that end-to-end testing would be great. Somebody should really write a blog post about that.
So, as I was saying. We continually run into an issue with our clients over defining requirements at the level that developers need to keep going, without getting bogged down in long stretches of design. There's a big gap between "users should be able to upload photos to their pages" and all the different details of permissions, validation and the like than need to be answered at some point. The Agile process suggests that those requirements be created as closely as possible to the code, which leads to the question of how best to keep the customer in the loop while the developers need these decisions to be made.
An easy-to-use tool that lets users read or create requirements that developers can build from and run as acceptance tests would be great. Somebody should definitely write a blog post about that.
Which brings us -- finally -- to Cucumber, a tool for creating automated acceptance tests. It's flexible enough to solve both problems. It can be used as a developer tool to drive regular TDD testing, and as a client tool for managing requirements.
Topics: cucumber, Ruby on Rails, tdd, Test Driven Development, Testing
Rails Test Prescriptions: Keeping your Application healthy is now on sale. This is a beta, partial release.
Rails Test Prescriptions is a comprehensive guide to testing your Rails application, covering both the mechanics of writing tests and the style for writing good and useful tests.
I'm excited to be publishing this electronically in a way that allows me to keep the book up to date as Rails changes over the upcoming months and years. Your $9 purchase entitles you to all updated versions for the life of the book.
Continue reading »
Topics: Ruby on Rails, tdd, Test Driven Development, Testing
So, if you're lucky, you've mostly missed another Internet pile-up about unit tests and so on, this one started by Joel Spolsky and some comments he made on his podcast.
I've already written a little bit about what Joel said, and I don't want to rehash that. But I have seen a recurring theme in arguments that testing is overrated -- namely that the testing that those people are writing about doesn't seem to be related to the testing that I actually do.
I'm going to put the summary up front:
Topics: Ruby on Rails, tdd, Test Driven Development, Testing
Just a quick note that the next two testing interviews are up on the Rails Prescriptions Blog:
Geoffrey Grosenbach of PeepCode and Topfunky.
Gregg Pollack of Rails Envy, the Rails Envy Podcast and Rails Activist fame.
Enjoy!
Topics: Ruby on Rails, tdd, Test Driven Development, Testing
Over at the Rails Prescriptions blog, I'm going to be posting a series of interviews with various and sundry Rails folks -- I'm cross-posting the first one here. To get the series started off, I've decided to use myself as a guinea pig and see if I can hold up to the grilling.
A couple of quick notes before I get to it.
And on with the interview.
Continue reading »
Topics: Ruby on Rails, tdd, Test Driven Development, Testing