Coding is like gardening...

Archive for the ‘testing’ Category

Announcing Rails Business (UK)

One thing I’ve always thought missing from the Ruby on Rails scene in the UK is a decent get together of Rails business people – those who run their own businesses like myself. There’s plenty of technical groups, or groups that meet in the evening, but I couldn’t find anything in the daytime.

The best way to get what you want is to do it yourself, right? Therefore I’ve created a meetup group for it. The main aim is to discuss such things as: best practices in running a rails consultancy (of any size), best-practice ruby on rails development/project management, this Rails Maturity Model idea that’s been doing the rounds in the last few weeks, plus anything else that’s relevant.

Anyone who’s interested in the same sorts of issues discussed in this group is welcome to attend. For more details of our first meeting on 4th March, see here.

Starting at Eden

Not many people can honestly say that they are actually doing their dream job. Many people have dreams and aspirations, and somewhere along the line they end up in a completely different destination. Life just has that way of sidetracking you, without you even noticing. That being said, on September 21st 2008, I walked into my dream job. Everything would be plain sailing from here on, the hard work had already be done getting here in the first place, right? Wrong.

From the first hour I realised that that these guys (and girl!) were good… really good. Not just that, they were talking in a completely different language to that which I was accustomed. Agile Development? Behaviour Driven Design? RSpec? Outside-in? Fixing broken windows… isn’t this a computer company? To say I was confused and a little scared at this point, would be an understatement. I still had a very big mountain to climb, in fact, my journey had only just started.

However over the last few months that I have been here, I have really started to grasp a lot of these concepts. Not perfect, or master them (that takes time and practice) but the value of them and how applicable they are to modern software design has blown me away. The concept of Agile Development and BDD isn’t completely strange and abstract, in fact, it’s quite simple:

  1. Write a story to explain the feature you are adding. (This can be done by the developer or customer)
  2. Run the story (it involves Cucumbers, i’ll explain some other time)
  3. The story fails (no code yet)
  4. Write a spec for the code that you will finally implement (This is the second layer of testing)
  5. Write code

The first 4 steps can be repeated a few times before any real code is actually written. When you do come to write code though, you know it works. How? The specs tell you so. It’s magic. Compare this to how I was taught software development in University:

  1. Write a design document (This explains the entire system and its individual components)
  2. Create UML diagrams and User Specifications for every Class in the system and how they interact
  3. Write code

Fewer steps, it must be quicker. What I didn’t mention was that the first two steps can take months alone. Often by the time that you actually come to write some code, a feature of the applications design has now changed, this means that has to be re-written and the diagrams all updated. Further delays. This monolithic approach is largely inefficient and frustrating!

So Agile Development works out better for the customer and better for us programmers (we actually get to do what we love doing!). Coupling that with strict testing at every step ensures fewer bugs and greater flexibility. You can approach each new feature/problem with confidence knowing that if any change you make breaks another part of the system, it will be caught by the tests failing. This is why the staff at Eden actually love doing what they do. They get to write awesome software, and have fun doing so. Compare this with the Games industry which is full of programmers who are overworked and burnt out. They were in what they thought was their dream job, but really wasn’t. I still have a mountain to climb to reach my new goals, but I’m having a lot of fun doing so!

Eden is a great company, with extremely talented staff. We have lots of really interesting projects spanning many different industries. I think this mountain will be quite fun to climb :)

Under the hood: RSpec as your early warning system

This article is part of our ‘under the hood’ series, where we examine coding concepts and techniques related to how we build our products and services for our clients. If you’re of a technical bent, then do check out other articles as they appear in our ‘under the hood’ category.

One of the most useful aspects of RSpec and BDD is how it can highlight areas of your code that are obvious targets for improvement.

When we write our specs before our code we are effectively writing the API, the contract that our code must fulfill. It’s often the case that if this contract is hard to write, or just looks clumsy, then there may be a better way to express it.  This makes RSpec our first way of detecting code smells.

Perhaps the easiest type of code smell to detect with RSpec is Law of Demeter violations. Imagine a simple Ruby on Rails task management application. Tasks can be owned by Users. There may be many places where we would want to show who owns what Task. The simplest way to do this in Rails would be to use a belongs_to association to expose the attributes of the User to the Task. This makes it trivial to get the name of the user who is assigned to a task:

class Task < ActiveRecord::Base
  belongs_to :owner, :class_name => "User"
end

# to get the owner name:
task.owner.name

While this is easy to write, it would make our specs more complex. Anywhere we wished to mock the name of the owner we would have to write something like the following:

task.stub!(:owner).and_return(mock_model(User, :name => "Bob Smith"))

There’s a lot of noise in this line. We’re creating a mock object just to produce the name of the user. Typing and maintaining test code like the above just seems unnecessary — we’re mocking more than we need. Perhaps worse, it doesn’t express our intentions clearly. We’re asking the task to return its owner, then asking that owner to give us its name. Instead of this approach, we can define the contract as we go and we can actually express our intention:

task.stub!(:owner_name).and_return("Bob Smith")

This makes our tests look tidier, but it actually has a more beneficial side effect. Even though we now have to write more code (speccing then adding the owner_name method to the Task class), it’s now the Task’s job to find the name of its owner. This makes our code more maintainable. For instance, imagine that not every task has an owner. With our original code, anywhere we explicitly used the owner association we would have to change the code to:

(task.owner.nil? ? "No Owner" : task.owner.name)

If this was used many times throughout our code base, we’ve suddenly got a large number of places to find and test this code. By defining the owner_name method early we avoided this problem because there’s only one place that now has to deal with the messy business of finding the name of the owner. Our other specs and stories aren’t broken because they can still happily call the owner_name method without worrying about how this is actually handled.

By using RSpec to help us separate out what information we want from how we get this information, we’ve made our codebase just a little bit cleaner and more maintainable.

The proof is in the testing

I am a recent convert to behaviour-driven-development (BDD) and this idea of writing stories and specs before writing code. Before I joined Eden Development, testing was always something that sounded like such a good idea … but I just didn’t have the time! Now I can’t imagine writing any code without tests. The idea seems positively frightening!

Here are some reasons why i have been won over by the test-first philosophy:

1. One thing at a time
Of course we all like to write very small concise functions, don’t we? But even in a small function, there are usually a few different paths that could be taken through it. It is so beneficial for me to think of scenarios one by one, write up the expected outcome, and then write the function a little bit at a time until it passes all the tests.

2. Confidence
Let’s be honest – who wants to go back and manually test all the things that you’ve tested a hundred times before and you’re pretty sure they’re still going to work? I used to be a tester – that was my job – and I couldn’t stand the monotony. But you can never have complete confidence in your whole system unless you have tested all of it. If you have broken something, it’s much better to know sooner rather than later. When you have a complete set of tests to run after every test you can be completely confident in your application.

3. Prove the obvious
Sometimes I’m writing a piece of functionality and I think, “Oh that’s so obvious – I don’t need to write a test for that!” But then I think to myself, if it’s so obvious then I had better make sure that it stays that way. In any case, it may not be obvious to the next person who works on this bit of code. It may not even be obvious to me in a few months time. So I write a test to prove the obvious. If somebody changes it and breaks the test, then they will be forced to think twice about the change they are making.

4. A greater understanding
Step-by-step stories are a wonderful way of understanding a system. Often when I’m coming to a piece of code I’ve not worked on before the first thing I do is work through the story. It may be enough just to read it through to see what happens when, and why. Sometimes I literally follow every step of the story, performing it manually to see for myself what it does. Once I understand what is supposed to happen, I’ll have a far better chance of following the source code. So be kind and write nice stories for the next person who comes along and wants to understand your code.

We write our behaviour-driven-development stories and specs using RSpec, and we are currently converting to Cucumber to run our test suites.