Programming Articles

Stop Refactoring your Damn Tests

Posted at 22:05 on Wednesday, 21 July 2010

PROGRAMMING A Ruby developer writing about testing? And writing about how he thinks it should be done!? What a shocking turn of events!

red, green, refactor!Test code exists to achieve, most importantly, two things. Firstly, to serve as an automated, low-level quality assurance. It’s used to passively weed out bugs and performance bottlenecks in your actual implementation so your team can feel a little more confident in their release — and in the case of libraries, to make the users feel the same.

Secondly, perhaps as a happy side-effect of writing tests for QA purposes, test code provides a great way to familiarise outsiders with your code by providing concrete examples of usage that actually work. The sweet little syntatic sugar provided by testing libraries such as RSpec allows you to recite a short example of how to use your code, and what the expected outcome is. Take, for example, this quick assertion. With a glance, I know that an Account has a method money_owed which should return a Float.

@account = Account.new
@account.money_owed.should == 1_213.94

For your test suite to work as a good QA robot and a friendly doormat, it needs to be:

  1. Working; lest you receive false negatives or positives when running it,
  2. Readable; lest the new guy on your team takes days instead of hours to acclimate himself with your test suite.

I’m sorry to say it, but these criteria can be easily broken by refactoring. As you are probably well aware; by the very nature of refactoring, generalising, and generally DRY-ing up any code you obscure what’s happening to some degree. As ugly and inefficient as it would be, you’ll understand much quicker when presented with 8 nearly-identical lines of code as opposed to a function that spits out other functions which then proceed to dynamically invoke a method based on a string fetched from an external environment-dependent configuration file.

And that’s good! Your implementation code should be clean, modular, readily extensible and with as little complexity as you can prevent. In many cases, like that of the nested if/else ladder that rolls 6-levels deep which gets transformed into a nice polymorphic block, refactoring can actually make things more readable.

So why am I railing on refactoring test code for killing readability? Well for one, your test suite is unlikely to have any branching conditions — that would kind of defeat the point. In order to do it’s job well, your test code needs to be simple, concise and definitely not complex. Sometimes in the process of adding functionality to your app your enthusiasm for making a great product can outrun your housekeeping ability, resulting in messy code — and that’s OK, you just return later and refactor it — but since there’s no new functionality being built into your test suites, there’s no real excuse for the code becoming a mess. There shouldn’t be anything to refactor.

No longer would your tests be prime examples of what should happen, but just a chance to show off how you can drop a class_eval to reuse these tests for other classes or modules — something that will require a lot of backtracing just to understand what your test suite is illustrating for a new developer — or maybe even yourself a few years down the line.

“OK, so I guess it can make my tests unreadable… but break them?”

You bet your ass it can break them. Your tests are most effective when they are applied against chunks of code that are a little more daring (for lack of a better adjective) than usual. Like the trapeze artist who prefers to leap through the air at the circus rather than sit in the stands munching popcorn (or some other analogy that doesn’t sound so dumb); good, maintainable code usually employs ‘daring’ techniques like long-winded inheritance trees and metaprogramming which could do with a bit of a safety net to warn you if your new, clean implementation isn’t behaving like it should. As such, you need to be able rely upon and trust your tests to do their job.

If you use the same ideas that you do to clean-up “real” code in your test code, doesn’t that tease the possibility of having to test your tests?

Instead, keep it high-level. Stick to the constructs provided to you by your choice of testing framework; chances are, they’ve already been tested themselves. My beloved RSpec, for instance, exposes some extensions to the lambda which enable you to assert changes in state as a result of a block of code:

@account = Account.new(:balance => 1250)
lambda {
  @account.deposit(3000)
  @account.give_dividend(2500)
  @account.withdraw(500)
}.should change(@account, :balance).by(5000)

The next time you find yourself writing test code, take a step back for a minute and decide if you’re going too far. If there is even a possibility that your tests could warrant their own test suite, I think you know what you need to do. If ever there was a code smell to trump all code smells, that would be it.

So please; for me, your team and for yourself, stop refactoring your tests to the Nth degree. Remember the two main reasons for which they exist in the first place — keep them readable, keep them reliable and let them do their job.

And above all else, test all the fucking time.

Tagged as: programming, rant, ruby, testing, bdd, rspec, refactoring

Sex, IronRuby and WPF

Posted at 16:25 on Wednesday, 10 March 2010

PROGRAMMING

IronRuby and WPF

SEX!

Now that I’ve got your attention, lets talk about IronRuby and WPF. Allow me divert your attention to another guest post I wrote for Eric Nelson, an architect and platform evangelist here at Microsoft.

You may recall about a week ago I wrote a a brief introduction to IronRuby, introducing some of the concepts, addressing the advantages of building with the .NET Framework and briefly talking about running pre-existing code with it to demonstrate compatibility. This time, I’ve taken it a bit further and gone through writing an application from the ground up — this time using WPF, the .NET libraries responsible for drawing awesome graphics, UIs and animations. On top of this, I’ve elaborated a bit on interoperability with the CLR.

This sample app I’ve built is what I consider the ‘hello, world’ of WPF applications — well, perhaps simply printing “hello, world” on the screen would be more apt, maybe this is more of a “bonjour, tout le monde” — an analogue clock face. A very simple data visualisation we’re all very familiar with.

Anyway I hope you enjoy the article, and if you happen to be attending the Scottish Ruby Conference later this month, please go ahead and pay Eric and I a visit. We’ll be happy to talk further on the topics of IronRuby, .NET, Ruby in general and maybe even Azure — more on that hopefully in a later post.

That link again is:

Tagged as: microsoft, programming, ironruby, ruby, src, wpf, .net

VIDEO_TS to DVD Image Converter in Python

Posted at 21:50 on Sunday, 28 February 2010

PROGRAMMING Just for fun, I’ve put together a nice UI for turning a typical VIDEO_TS folder into a disk image.

DVDI had to convert a whole bunch of typical VIDEO_TS folders to watchable-on-a-DVD-player disk images for a family thing.

You know when you want to just write a quick script to speed-up a monotonous task you’re doing, but the developer in you makes you want to turn it into a full-blown application?

This is one of those applications.

It’s just a simple python application that will present a nice, Tkinter-powered UI for hdiutil. Some people may find just calling the utility from the commandline might be a bit more flexible but convenience is always fun. It’s also very easily convertible into a .app bundle for Macs (although the availability of the hdiutil tool is going to be a problem on Windows).

It’s over here at GitHub

Tagged as: programming, python, dvd, video_ts, converter, open source

It just doesn't seem correct

Posted at 22:58 on Saturday, 18 April 2009 — with 193 comments.

PROGRAMMING The following both confuses me and makes perfect sense at the same time.

a = 22/7.to_f # => 3.14285714285714
b = (22/7).to_f # => 3.0

On the face of it, it shouldn’t make sense — but it does. Not unlike ATHF.

Tagged as: ruby, math, maths

Objective C for Rubyists

Posted at 23:48 on Wednesday, 11 February 2009 — with 2 comments.

PROGRAMMING I have a drastic love/hate relationship with Objective-C, the result of Apple’s (or rather NeXT’s) efforts to extend the C language with object orientation, a la Smalltalk. While it and Ruby do share some common ancestry, I could hardly describe my foray into learning Objective-C to be as fun as using Ruby and I have often strayed to things like MacRuby in times of weakness. Although, like it or not, Objective-C has quickly grown in popularity since the introduction of the iPhone platform into our lives and there is a lot more interest in it as of late.

Thankfully, the great Geoffrey Grosenbach has released a screencast spanning about an hour and a half with the intention of easing rubyists like myself into the hot water known as Objective C. Grosenbach consistently puts a whole load of effort into his PeepCode screencasts; they are my favourite method of learning at the moment and I believe they are worth every penny of the $9.00.

This particular episode is aptly named Objective-C for Rubyists and, for what it’s worth, I highly recommend it.

Photo of Edd Morgan

Edd Morgan is a software developer, amateur photographer, armchair critic, atheist and lover of all things technology.

Twitter @eddm

My Game Center username is 'eddm'; so all of you can add me and we can play one of the 0 games available for it.

about 8 hours ago

That's my Jam

Bonobo
 - Black Sands

Flickr Faves

Flickr Photo Flickr Photo
Flickr Photo Flickr Photo