April marks my 3-month-iversary with CookiesHQ – here’s the things I’ve learnt so far.
A little manual testing goes a long way
We try really hard to test everything in our apps at CookiesHQ. Every deployment goes through our Codeship CI server, which runs our test suite before deployments. As head dev, Nic is always pushing us to write comprehensive test suites that cover all scenarios – not just the “happy path” – and Nat’s dedicated Q&A sessions pick up anything we’ve missed.
However, there’s always going to be things that an automated test suite misses, and your test environment always makes certain assumptions – that a record will be present, or that a user will take a certain path. This is why a little bit of manual testing on the staging server goes a long way to validate that your test suite remains relevant, and that everything still works on a server that isn’t your local machine.
Communication is everything
Agile software development often means being faced with many small decisions every day. Since we don’t specify the behaviour of everything in minute detail upfront, questions inevitably arise during development. Rather than making assumptions on potentially important issues, it often pays to have a quick discussion with the client and clear up any uncertainty, rather than working on and commiting code you’ll only end up reverting later.
Pragmatism is key
Something that developers have to fight with on a daily basis is getting the balance right between elegant code and code that’s shipped. Often, you can have your cake and eat it, but sometimes there isn’t time to write something elegant and the more pragmatic solution – even it’s less DRY or a bit hacky – is better to get the feature shipped.
Baby steps are the best steps
Business logic for an app is often complicated. Although you can simplify most parts of an application, if the app needs e.g. an object with five different states, each with different logic at each step, it’s going to be complicated.
This is where focus comes in. Rather than trying to consider everything in great detail upfront, I’ve found it really pays to start with something small and simple, and layer on top of it, TDDing as you go along. App needs roles with authorisation? Build the feature first, then add on simple authorisation, then differentiate the authorisation based on the roles. Each step remains self-contained, making it easier to test and reason about, and builds on the step beforehand.
This is something I’ve still got to improve on, but it gets easier with practice ;).
RSpec is actually quite good
I hadn’t properly used RSpec before joining CookiesHQ, and was sceptical about the benefits. I’d been a committed Test::Unit/MiniTest user beforehand, and much of the FUD surrounding RSpec had put me off giving it a real. Since it’s our test framework of choice at CookiesHQ, I’ve had to use it everyday, and I’ve been pleasantly surprised. Being able to nest and group your tests is really useful, and the new
expect syntax feels much nicer than the older monkey-patching
.should syntax. Writing good tests suites is something I’m always working on improving, but I feel that RSpec helps, rather than hinders, in this direction.
Of course, like all religious wars in technology, there is no right answer, and sometimes it pays to ignore the arguments, try things for yourself and see if they fit with your tastes and way of thinking.