harriyott.com

The Blog

Continuous JavaScript Testing

Being used to NCrunch continuously running my unit tests as I type, I was looking for a similar solution for my JavaScript tests. I'm using Jasmine, which runs from a single HTML page. When I want to re-run the tests, I manually refresh the page in the browser.

Obviously this is a PITN, so by adding a meta tag I kept from the 90s, I've got my page refreshing every 2 seconds and running the tests.

<meta http-equiv="refresh" content="2">

Ninject Controller Testing

I've been converting an old, large project to use NInject to inject services and repositories into my controllers, removing the base controller's code that newed them up. I wrote a handy unit test to make sure all the bindings worked for the controllers' constructors, which caught a few missing bindings before it passed.

[TestMethod]
public void Can_create_controllers()
{
    var kernel = new StandardKernel();
    SiteResolver.RegisterComponents(kernel);

    typeof(AccountController)
        .Assembly
        .GetTypes()
        .Where(t => typeof(Controller).IsAssignableFrom(t))
        .ToList()
        .ForEach(c => kernel.Get(c));

    Assert.IsTrue(true);
}

Footballers on your software project team

Different roles in the software team map rather nicely to various types of footballer.

Developer: Striker

The player that actually achieves the goals of the project. Makes things happen, and gets the credit for a good result. Best paid.

Tester: Defender

Stops bad things happening, but nobody notices them until a bad thing happens. Any good things they do, they pass on to a striker, who will then do another good thing and take the credit.

Project Manager: Midfielder 

Organises everyone around them, does lots of chasing about, convinces everyone that they're a necessary interface between the defenders and strikers to encourage a beautiful game and prevent long-ball development.

Graphic Designer: Tactician or Performance Analyst

Fully-trained expert in their field whose input and ideas are sought and ignored by the players. Because any player or coach can come up with a tactic that looks good to them on paper, and the results are hard to measure without comparisons, they're seen as optional and expendible when there's a limited budget.

Client: Goalkeeper

Supposedly supplies content and photographs, but mainly just shouts at the other players when something has gone wrong and it's too late to do anything about it. Too often just kicks the bug right up to a striker, when they should throw it short to a tester.

Users: Fans

Will let you know instantly if they don't like anything without suggesting a better solution, even though they know they can do a better job than just about anyone on the team. There'll be a few that are always singing no matter what, and the manager will try to please them even if it doesn't make financial sense to.

The Perfect Geek Cafe

Today, Relly tweeted about starting a geeky teashop. I have spent time trying to find the perfect laptop-friendly coffee-shop, and so have a few feature suggestions.

Sockets

Each table should have sockets to power the laptops. Preferably, under the table, or even as part of the table. Tripping over cables is bad. 

Usage Guidelines

One of my bigger social awkwardnesses is working out how many coffees per hour I should buy, and whether that goes down if I have lunch, but then if it's only the soup, does it go up a bit again? What should I do if it gets busy? Should I give up my seat in favour of another diner, or am I just as valid a customer? Whatever they are, the guidelines should be clearly displayed at the ordering point, on the menu and the website.

Ordering

I'll tell you what is a nuisance; wanting to buy another coffee, but not wanting to leave valuables on the table to go to the counter, so awkwardly carrying a laptop, wondering if anyone would really bother to steal the charger, or should I take that too? Table service would be good, but could be seen as a way to force the customer to buy more or get out. A button, as used to someone flight attendants should be provided.

Also, twitter would be used for ordering. When you visit the cafe, you follow their twitter account, which will auto-follow back. When requiring sustenance, the order is DMed with the table number, and delivered when ready.

Lloyds Coffee House

Comfort Breaks

A bit like ordering, carrying a laptop to the loo is disquieting. This needs a bit more thought, but the flight-attendant button could be useful here too. Once summoned, the table attendant could combine keeping an eye on the customer's gear whilst clearing the nearby tables.

Wi-fi

Obviously free, fast, and the password clearly displayed, but a common problem with cafe wi-fi is that it stops working, and a reset is required. All staff should know how to reset the router. Resets would be requested with the flight-attendant button.

For bonus points, each table will contain a hub with CAT5 cables in place (probably glued or something).

Music

There wouldn't be any. Especially not Heart FM.

Managing the development process

To set the scene; three years ago, I started on a large software development project for a football club, and I was working as the sole developer. I employed the release-early-and-often approach, for a number of reasons. When the club got to use the software early on, they could see other areas that it could be used for, and so a couple of major additions were requested.

There wasn't much in the way of a spec, as the club wanted a prototypical approach so they could see how things worked before deciding how to proceed. It's not the most efficient way, but this was the first software project the club had commissioned. Hey, at least it wasn't waterfall.

The software was being used in production whilst development continued, which drove further requirements, and after a year or so, we had a stable release, and development stopped. The project was considered a success, and was being used around the world.

Project management

Being just me, I was the developer, business analyst, and project manager. Being mainly a developer, that was where I focussed my attention. I considered project management a lower priority, as I was the only “resource” on the project (n.b. I don't like being called a resource).

My process then was to keep track of the requirements in FogBugz. New features and bugs were either emailed or telephoned in by the one stakeholder who I dealt with from the club. We'd discuss which ones were the highest priority, and I'd update FogBugz accordingly. As a single developer, I could use the free version of FogBugz, and there didn't seem much point paying for a second user so the stakeholder could have access.

Once I'd finished a few tasks, I'd deploy a release to the staging server, and email the stakeholder with an overview of the changes I'd made, and asked him to check it over before it went live. Usually this was fine, but there were times when things were overlooked, and bugs or misunderstandings were uncovered only when users started using the live version in earnest. As I had different branches in git for live, staging and main development, it was quick and easy to fix and deploy a new version.

The Football League

Moving on

So, once finished, I moved on to some other projects, for a couple of years. A month or so ago, the club asked me for a new phase of development. They had been collecting some new requirements; small improvements to existing features, and some brand new things too.

I guess I've become a little wiser in the last couple of years, (and looking at the code, a much better developer too) and wanted to improve the process. The first thing we did was to meet up and talk through all the requirements in detail. This involved putting their list of requirements into a Google Drive document, me asking lots of difficult questions about what exactly things meant, but hang on, if we do that, then what happens with this other thing, and oh yeah, maybe we don't mean that, but actually we do, so we'll have to work round that by doing this, but perhaps there's a better way, and so on. I didn't let him off the hook on anything, so if he didn't understand what he wanted after all that, we got rid of it. 

We were editing the document as we discussed each feature, which meant a really tight feedback loop. I've seen people read a spec or requirements document, ask for some changes, and a week later, get another draft, and get bored because it's mostly similar to the last one, and even with changes tracked, it's hard to read and notice the differences, and it's really dull. This way, we did it all in real time. The next step was to convert this document into tasks; into a plan.

In one of my subsequent projects, working with a team of around half a dozen developers, a tester and a product manager, in a fairly agile environment, we used Pivotal Tracker to manage the workload. We found a few problems with Pivotal Tracker, and perhaps we weren't being as agile as we wanted to be, but it was mostly workable.

Since then, I've been using Trello to keep track of what I'm doing, but really only as a to-do list for myself. This time, however, I want to make the process much more transparent to the client, and for him to be more involved. Being free, I invited the client to Trello, and gave him access to the board for the project. A board is basically a list of lists.

I then added the following columns, or lists, to the board:

  1. Backlog
  2. Current phase
  3. In development
  4. Code complete
  5. In staging to test
  6. Testing failed in staging
  7. Testing passed in staging
  8. Live
  9. Done

Backlog

I went through the requirements / spec document, and for each discrete task, I added a card to the backlog column. I gave the card a brief title, and copied and pasted the requirement text from the Google document into the card description. Each Trello card has its own URL, so I copied and pasted that back into the spec document to allow easy cross-referencing.

Current phase

The idea is for the cards to migrate from left to right across the board's columns. Initially, we agree which cards from the backlog I should work on next, and put them in the current phase column. This week, I let the client do this himself!

In development

I pick which ever card from the current phase column, and move it into the third column. At this point, I may add a checklist to the card for the specific development tasks, so I can tick them off when I've done them. It makes me feel happy, and the card seems less daunting. Whilst I'm developing, I may discover more things I need to add to the list.

Code complete

Once I've finished development, the card goes to the right again. I'll add another checklist to the card, for the acceptance tests, which I'll describe in a bit. I'll then work on the next card in the current phase. Once they're all done, then I'm ready for a staging release. The client may not be ready, however, if he hasn't finished testing the last staging release. This is fine, as he has plenty of his own work to do. I'll just add another item or two from the backlog into the current phase and continue developing.

In staging to test

Once we're both ready for a staging release, I rebase the staging branch in the git repository, and deploy to the server. I'll move all the cards from the code complete column, which all have acceptance tests.

To avoid the problems I used to have with bugs appearing on the live site, I've made a bigger deal of the client testing on the staging site. A quick look over is no longer good enough. Each card has enough tests in the checklist to cover the feature, and is based on the requirements, which are handily at the top of the card. The client can add extra tests too. He then works through the tests on the card and ticks them off when they pass.

Testing failed in staging

If any one of the acceptance tests fails, the card is moved here, with a comment from the client explaining why. There have been other reasons for cards ending up here, which have been useful too. The client has noticed that a feature wasn't completely defined, or once he's actually used it, something else needs changing. Technically it isn't a bug, or perhaps even a legitimate reason to fail a card, but it raises the problem, so it's a good thing. In these cases, I've added a new card to the current phase describing the enhancements, which then follows the usual process to the right. The original failing card is then considered to have passed, and moves to the next column.

Valid test failures are then moved back to the current phase. If the testing hasn't started immediately after a staging release, this could be a problem, as I'll have already started a new phase, and have new cards in the second and third columns. I saw two ways round it; a new column for failed cards in development, or to distinguish the cards in the existing columns. Using Trello's labels, I marked failed cards that are back in the current phase with an orange label, so I can clearly see the difference. I checkout the staging branch in git, and work on the fixes as a priority.

When all the rework is complete, I do another staging release.

Testing passed in staging

Once all the tests have passed, we are, in theory, ready for a live release. I make sure I ask the client if he really is ready, I rebase the live git branch from the staging branch and deploy.

Live

The cards are moved into the live column. In the last release with delayed testing, another phase was ready for staging, but had to wait, like a train at a signal. Once the code was deployed to live, I released the next version onto staging for testing straight away.

Done

There is the possibility that something breaks the live site, so I keep a separate column for done. The most recently deployed cards are left in the live column, as a reminder for me in the event of a bug report from the live site. As it happens, there haven't been any yet. Before doing a new live release, I'll move everything from the previous release in the live column to the done column.

Wrapping up

I've made an example board with a single card you can look at.

I've found the benefits of this approach are that the client has more visibility into exactly what I'm doing, and the current progress and status of the project, which helps when his boss asks how things are going.

The releases are more stable, and the client is more confident of the quality of the code.

I'm happier, and more relaxed, as some of the responsibility is now with the client. We all know that developers are the worst people to test their own code. In the absence of a trained software tester, a happy client is the next best thing.

In all, I wanted to explain how, as a one-man-band, I manage a project. I'm not claiming it is the right way, nor that it should be labelled agile, nor that I won't change it. If having read this, you choose to review your process, by taking on some of my ideas, or working out your own, then that's great.

Really, the previous paragraph is partly a pre-emptive strike against potential commenters wanting to tell me I'm doing it wrong. I feel a little vulnerable admitting past mistakes, and possibly current ones too, but this stuff doesn't come as easy to me as coding.