-
Get a monthly update on best practices for delivering successful software.
Anther interesting item from yesterday's earnings call:
Over 90% of iPhone apps are approved within 14 days of submission.
Given over 100,000 apps in the store from a wide variety of developers (from amateurs to experts) and a wide variety of topics, that's actually pretty good. Apple claims that most rejections are actually for bugs in code, which makes sense given the wide disparity in development quality and test coverage.*
* For example, are you testing your software for ipod touch as well? You should - applications have been rejected for working on the iPhone, but not the iPod touch.
Topics: ap store, iPhone, ipod touch, Testing
So we just went through this humongous (believe me!) effort of upgrading the technical platform for one of our existing Rails applications that was running Rails 2.1, Ruby 1.7 and Mongrel cluster. The goal was to upgrade to Rails 2.3, Enterprise Ruby 1.8.6 and Passenger. It all started out as well as you would think. Updating the Rails gem, Ruby version, installing/configuring Passenger and updating relevant gems was pretty quick and smooth. Some quick and dirty testing of the application did not reveal any major problems or issues. Great! You are thinking the upgrade is mostly done att this point before you move on to the tests in the application!
Tests
Tests can prove to be major hurdle in upgrading Rails applications. In our specific case, close to 70% of the tests were either broken or failing due to a number of reasons. Actually, the number of broken tests was way way greater than failing tests which led us to think the changes in the Rails testing API caused most of these issues. Some of the issues were also caused by a plugin or gem that was used to support the tests not being compatible with the new API. It took us quite a bit of effort to figure out the reasons for the issues and also find the fixes.
Continue reading »
Topics: Ruby on Rails, Testing, Upgrade
The problem: I needed to display a warning to a user if the data they were looking at was more than 90 days old.
The solution: Create a method that takes 2 dates (either DateTime or Time), and returns the number of days, or hours between them.
def self.difference_in_dates(date1, date2, unit = 1.day) return nil if date1.nil? || date2.nil? || unit == 0 (( date1.to_time - date2.to_time ) / unit).round.abs end
The problem was simple enough, and my tests were all passing, so I moved on to my next task.
That code has been out in production for several months, but earlier this week, a new developer told me he got an error when running the test:
NoMethodError: undefined method `to_f'
for Mon, 21 Sep 2009 14:29:38 -0500:DateTime
(we're running this in Rails 2.0.2)
I looked at the code, knowing it was working before, ran the unit tests myself, and didn't see the issue. Now I'm on Windows and everyone else is on a mac, so as soon as I run into an issue that no one else has seen I want to prove if its a Windows problem. But wait, this test has been running in our Continuous Integration server (Hudson) for months, and no one else on the team ever had any issues with it, and the code has been working in production without any errors in the logs.
I jumped into rails script/console to see what's up, and here's what I found:
>> x = DateTime.now => Wed, 23 Sep 2009 00:00:00 +0000 >>; x.to_time => Wed Sep 23 00:00:00 UTC 2009 >> x.to_time.to_f => 1253664000.0
Which is what I expected, but when I asked the other developer to run that same instruction, he got an error.
>> DateTime.now.to_time.to_f NoMethodError: undefined method `to_f' for Mon, 21 Sep 2009 14:29:38 -0500:DateTime
What's up with that? We're running the same code, and all of our libraries are the same version. Looking at the date value in his error, I saw the timezone, and decided to try this variation locally:
>> x = DateTime.parse("2009-09-21T14:29:38-0500") => Mon, 21 Sep 2009 14:29:38 -0500 >> x.to_time.class =>; DateTime
So I'm gathering that when there is a timezone and you ask DateTime.to_time, its just going to give you back a DateTime.
Continue reading »
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.

Rails Test Prescriptions, the eBook put out by Noel Rappin, Director of Rails Development at Pathfinder, has been picked up by Pragmatic.
Congratulations to Noel - he's done a great job of furthering testing best practices in rails, and this is a great reward. As he said "I’m very excited by this. I’ve wanted to work with Pragmatic for as long as they’ve been publishing books, and I’m thrilled that this particular project will be able to get wider distribution and access to Pragmatic’s editorial expertise and skill."
* The current free “Getting Started with Rails Testing” ebook will continue to be available. If, at some time in the future, there’s a better Getting Started tutorial in the Pragmatic book, it may be offered as a replacement.
* The update site for current Rails Test Prescription owners will continue to be available for the foreseeable future.
* There will be one more official update to the current Rails Test Prescriptions, probably around the end of August. This will wrap up the chapter or two I’m working on, and tie up some other loose ends.
* After that, errata and information about changes to test tools will most likely be handled via this blog and an errata page on the rails test prescriptions site.
This is Noel's 4th book with a major publisher, following Professional Ruby on Rails, wxPython in Action and Jython Essentials. We're happy for Noel and happy to have him at Pathfinder.
Related Services: Ruby on Rails Development, Custom Software Development
Topics: rails testing, Ruby on Rails, Test, Test Driven Development, Testing
I had to dig into a production issue the other day that presented itself like this:
There was a piece of javascript code that iterated over some dom elements, gathered ids into 2 arrays, ran a validation check, and then flattened the arrays to add them to the url.
On firefox, opera, and chrome this was working correctly, and had been tested by the developers, but on IE 7 it isn't working, and the problem wasn't detected until it made it out to production. (Which raises a point about testing in IE during QA, which I'll get to in a sec).
I started my investigation doing what I'd call "poor man's debugging", putting some alerts in, breaking up the code a bit to make it easier to inspect, etc. Normally I don't do this when testing in Firefox, because I have Firebug, but in IE I always seem to start with the basics to get my bearings, then quickly move to a more pragmatic approach.
Then I started using firebug-lite, confirming that I can see the info I need, and I reverted my changes to the code so that I could verify that I hadn't introduced any issues.
Continue reading »
Topics: Ajax, Javascript, Prototype, Testing
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.
I've been doing a good deal of PDF generation in Rails, and had to go through the process of comparing all the available techniques and frameworks in order to find the right solution for my needs.
Its great that there are so many tools out there, but it can be a daunting task to figure out which is best, which will scale, which will continue to grow and improve, and to evaluate the true 'cost' of free vs. commercial.
With all this info finally digested and sorted out, I was surprised when I got a client request to be able to add a banner to an existing pdf, and from what I can recall, none of the libraries I know about seem able to do this. Right now, I'm in the middle of googling the hell out of it, but haven't found my silver-bullet answer yet. (maybe I should ask jeeves?)
I've done various searches and have come across a few categories of PDF tools:
I did find a discussion about how this could work on Google Groups between Greg Brown creator of Prawn and Ruport, and James Healey developer of PDF::Reader, but that discussion basically ended with, "Yeah, that would be cool!".
At this point I'm looking into the Origami library which is actually designed for pdf 'security' and testing, and isn't explicitly designed for editing pdfs in this way, but at the moment its the leading candidate in my list.
Have I missed something? Is there an obvious way to do this in ruby/rails that I'm completely overlooking? (I haven't looked very deeply at tools that shell out to the bigger libraries, but I wouldn't rule them out)
The initial requirement was to be able to add a banner/header to an existing PDF, but I can see the complexities of determining how to shift the existing content down without screwing up all the formatting, so I think even being able to insert a coverpage might be a suffcient implementation for now. (Maybe I should be searching for pdf 'merging' instead of editing)
I'll update you with my final solution in an upcoming blog post, and I'll be covering all of the info I've learned on PDF Generation tools for Ruby and Rails at this year's WindyCityRails Conference on September 12th. Drop by http://windycityrails.org to register. (early registration ends Aug 1st)
As sort-of promised in last week’s post, I’m going to work through a real-world test example, with an eye toward explaining how and why I tested the way I did. Hopefully, I’ll be able to do this at blog-post length. If not, well, there’s always next week.
This site, which was a legacy rescue, allows users to send messages to each other within the site without having to give away their other contact information. The problem is that nefarious spammer types were creating logins and immediately sending messages to large numbers of the user population, irritating them. After some deliberation, the client decided on a rate-limiting strategy, where a member could only send a certain number of messages in a day, and a new member could send even fewer messages a day. Messages above that point would require administrative action to unblock the user’s privileges.
Topics: rails testing, Ruby on Rails, Test Driven Development, Testing
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
It's been way too long since I blathered on about style issues. Today I'd like to talk about testing style. This article assumes you are already writing tests and already using something approaching a Test-Driven Development process -- I'm not here to argue about process, at least not today.
Today the topic is the actual construction of individual tests, how to name them, how to group them, where to get data from and the like.
I suspect I'll think of five more things right after I post this, so look for an update sometime in the future. The update will also address all the places where everybody tells me that I'm totally wrong.
Topics: rails testing, Ruby on Rails, Test Driven Development, 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
I mentioned last week that the RubyMine post was replacing what I had meant to write about. Well, this week we finally get to it...
It's been about ten weeks since I wrote about Cucumber the first time and the second time. Since then, I've continued to use Cucumber and now seemed like a good time to update some thoughts on how and why it seems to be working for us.
The big headline, of course, is that I'm still using it after ten weeks. I'm pretty quick to abandon tools that aren't pulling their weight, so just the fact that Cucumber is still in the toolbox means that despite the time that it takes to write Cucumber tests and step definitions, I'm finding the process of writing the tests and the tests themselves to be valuable.
Topics: cucumber, Ruby on Rails, Test Driven Development, Testing