Saving the planet, one website at a time

Hi, I'm th3james. I build stuff with Coffeescript, Clientside MVC and Rails

TDD Is a Feedback Tool, Not a Religion

ICYMI, there’s currently a discussion going on around TDD, after DHH declared it ‘dead’ at RailsConf 2014. This lead to a discussion series between himself, TDD legend Kent Beck, and Martin Fowler, the second of which took place on Google Hangouts yesterday:

In this discussion, David makes the claim that TDD leads you down a path of aggressive and unnecessary isolation of your code, citing ‘Hexagonal Rails’ as an example of the damage that TDD does when applied absolutely:

https://gist.github.com/dhh/4849a20d2ba89b34b201

I think most people would find the code in the example pretty poor. The intent of the code is heavily obscured, and I find it hard to read. This kind of isolation might make sense when working on a larger, more complicated domain, but given the complexity of this example, it’s absolutely overkill.

The question is “Was TDD responsible for the author arriving at this design?”. DHH paints hardcore-TDD practitioners as dopamine addicts; constantly craving their next fix of the ‘Red-Green-Refactor’ cycle, they will do anything to make their speed though this cycle quicker. It’s certainly true that code this heavily isolated is easy to unit test.

It shouldn’t be a surprise that TDD acts as a force on your code, that feedback is the reason we choose to write tests first. Gary Bernhardt’s post Test isolation is about avoiding mocks touches on this idea:

“Most of us think that small functions are better, yet hundred-plus line functions are common […] The reason is that there’s no pressure exerted on us.”

TDD applies this pressure, by forcing you to interact with the APIs your code exposes, and create the dependencies it requires. This feedback acts as a tool which helps you feel the pain in your design.

However, this doesn’t mean that to practice TDD is to surrender all control to our tests and powerlessly slip into an obsession with faster and smaller units. It remains up to the developer to interpret test feedback, amongst all the other feedback and intuition that they have, and make sensible decisions.

The vast majority of people using TDD do not blindly let it destroy their designs, creating an ever expanding number of classes, repositories and service objects. Instead, they see it for what it is: Not a silver bullet or religion, but a tool which helps you make better design decisions.

Before I wrap this up, I’d like to thank DHH, Kent, and Martin for having these discussions. Despite some of the more troll-y posts, I think the general dialog around #isTDDDead has actually sparked some quality debate, and it has driven me to some new insights about how I write and test code. Hopefully we can all remember we’re still figuring this out, and treat this as an opportunity to learn.

Testing Code Is Simple

A.K.A. “What I wish people had told me about testing”

Test driven development is now widely recognised as ‘a good thing’, but for developers who aren’t already practicing it, the world of TDD can appear quite compilicated. Choosing a testing framework and assertion library, picking between factories and fixtures, deciding how to handle database state teardown, how to mock objects, what’s the correct phrasing of my tests… From the outside, the world of automated software testing can seem like more work than it’s worth.

These issues put me off doing diving into TDD for a long time. Having been testing for a while now, here are some of the things I wish people had told me before I started:

Testing software is actually pretty simple

Writing software tests consists of the following steps:

  1. Write code that interacts with the code you’re building
  2. Write assertions about what you expect to happen
  3. There is no step 3

Let’s go through an example. Recently, I came to be working on a large client-side JavaScript application. Coming from a Ruby background and having never tested JavaScript before, I wondered what was the simplest setup I could create for testing would be. Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  // tests.js, include this on a page with your application code

  /* Our testing library */
  assert = function(result) {
    if (!result) {
      throw new Error("A test failed");
    }
  };
  /* end of testing library */


  /* tests */
  // MyMathLibrary.add given 2 arguments returns their sum
  result = MyMathLibrary.add(1, 2);
  assert(result === 3)

That’s it. Run this in your browser, if you get an error in your console, your tests are failing. If not, congratulations, your tests are passing. The extent of our testing library is one function called assert, that throws an error when given a false value.

This is genuinely all you need to start practicing TDD. Write a short description of expected (but unimplemented) behavior, write some code that creates context and assert the expected state. Then write code to make it pass and repeat:

1
2
3
  // MyMathLibrary.multiply given 2 numbers returns the multiplication of the 2
  result = MyMathLibrary.multiply(5,3)
  assert(result === 15)

Just start writing tests

Writing well factored, fast, maintainable tests is tricky, and a different skill from writing good code. Expect to be bad at it at first. Don’t let this put you off: One of the best things about tests is that even poorly written tests can produce a large amount of value. Just start writing tests and learn as you go.

Testing is not a DSL

RSpec has a lot to answer for. Most developers starting (particularly in Ruby) will initially be confronted by the ‘spec’ style of writing tests. I think this is unfortunate, as certainly for me, and I expect for many others, it obscures the fact that tests are just code and assertions. For this reason, I would recommend when starting testing that you avoid the ‘spec’ style syntax, and instead master the basics using the ‘test’ or ‘unit’ style syntax.

1
2
3
4
5
  # An example in Mocha.js using the 'qunit' syntax
  test('MyMathLibrary.multiply given 2 numbers returns the multiplication of the 2', function(){
    result = MyMathLibrary.multiply(5,3)
    assert(result === 15)
  })

Keep your test setup simple to start

When you start testing, most people will recommend a laundry list of libraries you should use to start testing. Mocking, Factories, Transaction tests… All useful features, but when you’re starting out, I’d recommend keeping to a bare minimum: a testing framework for reporting passing/failing tests and an assertion library to get better error messages. My personal picks are:

Javascript:

  • Testing: Mocha.js (using the qunit syntax)
  • Assertions: Chai.js (using the assert syntax)

Ruby:

  • Minitest (using the unit syntax)

After you’ve written tests for a little while, it should become clear why (and if) you need factories, mocking and the rest. Then is the right time to start using them.

Summary

Testing your code is not only the path to fewer bugs, easier maintainence and confident refactoring, it’s also hugely satisfying. As such, it’s not surprising that so much tooling and methodology has sprung up around it. For the most part, these are good things. However, when starting testing, it’s easy to confuse these tools and processes for testing itself. I hope this serves as a call not to run before you can walk, and a reminder of the core simplicity of testing.

Regardless of how you choose to test, the most important thing is that you are doing it. Good luck

BrowserLoop: Remix Music in Your Browser

I’ve just finished building a tool which let’s you remix loops of my band’s newest single. It’s build using Backbone.js and Coffeescript, and uses HTML5 audio to play back the ‘loops’ which make up the track. It’s pretty cool, give it a try:

Try BrowserLoop

The app works by setting up a Clock object at the BPM of the track, which then uses setTimeout() to fire a Backbone.event for each beat, which each of the loops then listen to. By default, HTML5 audio does not loop seamlessly, as there is a slightly delay when seeking to the beginning of an audio file, then restarting. To get around this, I load each audio file into 2 audio tags, and switch between them with a ~50ms overlap. This isn’t always completely reliable, so there is a slider to adjust this overlay at the bottom of the app

Check out the source code on github

Unfortunately, mobile devices (iOS etc.) don’t support pre-downloading HTML5 audio and video, which means the site doesn’t work on them. This is apparently done to stop users racking up data usage on 4G, as the files are only downloaded once the user clicks play. It’s is a shame, because I’d have loved to use this on the iPad!

It’s also worth noting, I built this using a tool I’m developing with @amulligan to make building Backbone.js apps easier, but more on that later :-)

Th3james’ Blog IV: A New Home

So, posterous is dead, so I’ve been forced to move this blog to a new home. Perhaps foolishly, I’m trusting another free provider (this time, github) to host my blog. I am at least running Octopress this time, so migration should be easier.

Anyway, apologies for being a bit quiet on here recently, but I’ve been busy with lots of exciting stuff to do with Backbone.js which I’ll be releasing over the next few months.

Backbone.ViewManager - a Backbone Extension to Stop View Memory/binding Leaks

Recently when working with Backbone I discovered how easy it was to leak Backbone Views into memory by not taking care to unbind all events listeners associated with views before discarding them. This issue is discussed at length by Derick Bailey in his post about backbone ‘Zombie’ views: http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

This issue for me was particularly pronounced when swapping objects in and out of a ‘content’ DOM element, quickly ruining my apps performance. So, I wrote a library that extends Backbone.View to help keep reference of view bindings, and dispose of them when discarding. I call it Backbone.ViewManager, take a look over on github:

https://github.com/th3james/Backbone.ViewManager

Fixing Locale Issues Over SSH After Zsh Upgrade

I recently upgraded to the rather nice OhMyZsh, which I was enjoying, until SSH’ed to one of our Ubuntu servers, tabbed to auto complete, and was presented with this message:

-bash: warning: setlocale: LC_CTYPE: cannot change locale (en_GB.UTF-8)

… each and every time I tabbed. Needless to say, this gets pretty annoying fast.

I tried a few solutions on the internet, before stumbling across this post which pointed me towards /var/lib/locales/supported.d/local.

To fix the issue, you need to add a line to that file for the locale that bash is complaining about:

en_GB ISO-8859-1
en_GB.UTF-8 UTF-8

Since UTF should be the same for each locale, we just point en_GB.UTF to UTF-8 (this is probably the same as the default locale your system has).

Once you’ve done that:

sudo dpkg-reconfigure locales

Login/logout and enjoy working tab completion again.

Understanding Undefined, Null and Testing Variable Assignment in Javascript

During a code review a college suggested that we could change one of my javascript switches on an non-existant value:

Which seemed to make sense because, since we don’t want to perform any type coercion on the null object, this should be faster.

However, when I reloaded the page, the comparison (previously returning true) was now returning false. Confused, I fired up the web inspector to discover this:

Ok, so evidently null and undefined are different things, even though I’d been using them interchangeably (like many web developers, I made the mistake of diving in javascript without bothering to learn it…)

Undefined and null

So what exactly is the difference between the two? Undefined is the default value javascript variables take before they are assigned a value. Null, on the other hand, is the intentional absence of a value. When using ==, the types of both undefined and null coerce to false.

The many meanings of undefined

So, you can just do this:

and in most cases, that will work. However, undefined is actually 3 things in javascript; a type, a value and a variable. The issue with the above code is that we’re not checking if the some_var is ‘undefined’, we’re checking if it’s equal to the global variable called undefined. Undefined (the variable) exists uninitialised in javascript in the global scope and like all uninitialised variables, it is set to undefined (the value). For more detail on this I highly recommend checking out Angus Croll’s post on the subject

The problem is, somewhere in your code or in a library, someone else could overwrite the undefined variable to be a string:

Which would mean all your comparisons to undefined would compare to a string! There’s no good reason to do this, but given the potential for javascript variables leaking into the global scope, it’s worth not comparing to the undefined variable in case someone in a library or other javascript file has accidentally (or maliciously!) overridden it.

It’s worth noting that ECMA 5 forbids setting the value of undefined, but currently, only Safari enforces this.

Comparing the types

So if we can’t compare to the undefined variable, what should we do? Remember I said that undefined was also a type? Well, an uninitialised variable’s value is still of the type undefined. So we can use javascript’s typeof method to get the values type as a string:

Hopefully this clears up not just how to test assignment correctly in JavaScript, but also why we do it this way.

Using PJAX With Rails to AJAX Navigation

PJAX is a javascript library which was mentioned by DHH in his Railsconf 11 keynote

In their own words:

pjax loads HTML from your server into the current page without a full reload. It’s ajax with real permalinks, page titles, and a working back button that fully degrades.
pjax enhances the browsing experience - nothing more.

https://github.com/defunkt/jquery-pjax

PJAX makes navigation much faster and feels more like using native app than a website. While only loading parts of the page through AJAX isn’t exactly a new thing, PJAX makes it easier to add it unobtrusively, with proper URLs and a working back button.

The project appears to be pretty new from the github page, and there isn’t a lot of documentation, so I though I’d document how I got it working with Rails 3.0

Adding PJAX to your project

First, you need to grab jquery.pjax.js and add it to your project (Oh, you’ll need JQuery too, but I’m guessing most of you have it anyway :-)

Next, add some javascript to your application.js file (or whatever your sitewide JS location is) to tell your chosen links to send using PJAX:

This code tells the browser to send all the links in ul.menu using pjax, and to load the results into the #main

This alone isn’t enough to make PJAX work. PJAX sends the request through AJAX, but if the response contains the <html>  tag, PJAX considers it a full page response, and reloads the whole page.

So, to make PJAX load the returned content into #main object, you must only return the HTML fragment, without the layout around it. To do this, you simply do a render :layout => false. However, adding this to ever controller action soon get’s pretty tedious.

Not returning a layout on PJAX requests

Thankfully, PJAX helpfully adds ’X-PJAX = true’ to its request headers. So, to return all PJAX requests without the layout file, it’s simply a case of checking for the header parameter, and adding :layout => false if so.

I did this by hacking the Rails render method:

This was the best approach I could find to do this for all requests, if anyone knows of any better ways, let me know!

That’s it!

This should be all you need to do to get PJAX working in Rails 3.0, you should find that navigation on your selected elements happens using AJAX requests in supported browsers (basically anything not IE).

You can see it in action on my band’s website:

http://barcodechannel.com

Styling Active Links in Rails

We often want to style active links in our Rails to improve the users perception of their location in a given website. However, a:active is rarely sufficient when you’ve got sub menus on your site.

I went searching for people who’d already tackled this problem and found the post by ‘jammanbo’ on this page:

http://www.ruby-forum.com/topic/178087

jammanbo’s helper detects if the current path matches another path’s controller and action, returning ‘active’ or ” to use as the link class. While this is useful, there are many times when we want to match to a different level of specificity for links. For example, top level menus in sites I’m working on tend to match a controller, and sub menu entries to the action. Other times, we also want to match the route’s parameters.

Taking this into consideration, I came up with this helper:

This helper returns a string, either ‘active’ or ” depending on if the URI parameter matches. The optional second parameter defines the specificity, either

  • :action (default) match both controller and action
  • :controller match just controller, or
  • :complete matches all parameters in the route (except extra ?param=whatever)

To use it, simply drop it into your ApplicationHelper, then start styling links with:

Have fun!