code development programming

Software Development as a Christmas Story

Gingerbread Christmas Tree
Oh Tanenbaum

We decorated the house for Christmas. A smaller project than most of the software I’ve worked on, but a useful reflection.

The Cost of context switching

Sometimes, in the middle of one task, you need to do another. Either because you were interrupted, or because you weren’t prepared. Consider the tree, a tall tree, one you need a ladder to decorate. But you left the 🌟 in the attic.

You don’t just have the cost of picking up the star, you need to get down the ladder, fold it up, carry it upstairs, open the attic, unfold the ladder, climb to the attic, find the star, then pick it up and unwind all the other steps just to get back where you stated before you can continue the task of putting the Star on the tree.

It’s just a minute to get the star…

Yak shaving

Sometimes it’s more than just one thing. Sometimes to get to where you need to go, there’s a cascade of other tasks.

You want to put the tree up, but it’s the first time you’ve had a real tree, so you need a new base. It’s bigger than last year’s tree, so your lights don’t fit. So you need to go to the shops. But you need to fill up your car. And the tyre pressure warning light comes on so you need to top them up. And you need to check the tread depth whilst you’re there, and so on.

Programming in a nutshell

Performance at scale

Our tree stood up fine when it was delivered. But as it scaled out and the branches widened, it pushed against the wall, making it unstable in the condensed space. It fell over.

Luckily no lights or baubles were using it at the time, but it’s an interesting challenge holding up a heavy tree in one hand, trying to adjust it’s position with the other hand, as I avoided the puddles of water in the floor as my wife mopped them up. If you’ve ever worked support, this may sound familiar.

Turns out that it was harder to stabilise than I anticipated.

The branches were unevenly partitioned, providing more load on one side, so I had to stabilise it against the wall. And the tree was almost a foot taller than expected, which turned it out to be 2 foot taller than the base was rated for.

We upgraded the base to handle the load. It’s bigger than we need.

Technical debt

I have some old pre-LED tree lights and they slowly fail so each year I replace the unlit ones from the packet of spares but I haven’t been replacing the spares. Eventually, they will run out, and the spares will no longer be available. I’ll have to throw them all out and start again.

The new led ones don’t let me replace them individually. But they last longer and are cheaper to run.

Which debt is easier to live with?

With a big tree, those old lights aren’t long enough. So, do I buy another set for the rest of the tree that doesn’t match them, or throw out the existing ones and buy a longer set? The latter looks better, but throws out the sunk cost along with the lights.

You know computers, can you look at this for me?

No, I can’t fix your tree. I can navigate a garden centre. I know enough physics to keep a tree upright, eventually, and safely put the angel on, but I’ve no Idea how to grow one, or what that weird stand with 17 gears you bought does, or how to assemble your plastic one. And I’ve no idea what that bug in the tree is.

Merry Christmas. Catch you all in the New Year.

development ux

User Experience : A quick introduction for developers

The following is an internal summary I wrote for a team that no longer exists, summarising a number of references from UXScotland, various book and blog posts. It extends the thoughts from my Pecha Kucha talk. For more details, please refer to the links throughout and the references at the bottom. The context here is consulting and long-term B2B projects, but some of these discussions are more widely relevant.

User Experience : Project considerations

User experience is about making sure we are solving the right problems in the right way. It is the intersection of design, users, and context. Context here is a combination of one or more of the device in use, the user’s location, any social cues such as nearby friends, and anything else that may be available from sensors or historical information.


In many cases, the requirements we have are assumptions (e.g. what users want is Facebook integration). Where the benefits of a requirement are unclear, we should treat it as an assumption to be tested. Embrace data, and analyse it.

At the requirements stage, we need to make sure we are solving the right problem (pretotyping : “building the right *it*”), and that our chosen design helps the user to solve the problem without frustration (i.e. prototyping the design, rather than the implementation, with wireframes/sketches).

In user testing, particularly in an agile development, we can refine those ideas by seeing how well the implementation solves the problem, by testing with users. We can also test deployed code by analysing heat maps and http logs to see what users are doing to inform further tests and the assumptions that feed into further design cycles.

In a Lean/Agile project, we need to be explicit about our assumptions about the user and test them at every stage of the development to ensure that we always meet user needs.


How does UX fit in our process?


A system that supports user’s need effectively will need to understand that the user is a Stakeholder in the process. Whilst the users themselves may not be directly involved in the generation or review of design artefacts, there should be a user representative, either a super-user on the customer side, or a 3rd party researcher who has determined user needs, and has authority to verify any proposed solution and high-level requirements against those needs.

Functional Requirements

Personas / Typical Users

A persona is an abstraction of a system user. In a simple system, there may be only one type of user, but more sophisticated systems will typically have users and administrators, and may have multiple classes of each. A persona is defined to encapsulate the types of tasks a specific user may wish to perform, and any limitations that may be imposed (for example, administrators may be able to install specific browsers or client software, but members of the public using the system must be supported across multiple browsers at multiple screen sizes).

User Journeys

Each persona will have one or more tasks they wish to perform in the system. A User Journey describes the tasks as a series of steps that a specific persona will follow in order to achieve that task.

Consider the tasks that a user wants to perform. See also BDD – design from user in.


User wants to process a case:

  • User logs in to the system
  • User selects case from their task list
  • User reviews latest document
  • User finds agent for case, and calls to discuss
  • User adds comments to case
  • User saves case and returns to their task list

This process may identify a new use case (“Display task list”), and specific actions that need to be defined within a use case (“Display latest document” and “Display agent contact details”)

The User Journeys provide the context between the Stakeholders (and User Types therein) and the Use Cases. Each User Journey will link to one or more Use Cases, but some Use Cases may not have an associated User Journey (nightly payment processing, for example).

User feedback

If the solution is replacing or improving an existing system, the best source of information on the current system are the users. The requirements capture process should take into account both the tasks that the users perform and gather feedback on any areas of frustration. The prioritization exercise should consider these improvements as well as new functionality.


As well as testing the Use Cases for functional acceptance, the FAT/UAT process should also test that the final system supports the User Journeys defined up front.

On-going support

Where projects have regular support meetings, the input of users has been valuable in identifying problems areas and possible changes. When on-going service delivery contracts are defined, SDMs should consider whether ongoing user feedback is appropriate as part of the planning and scoping of releases within that framework.

Questions to ask

  • Have the requirements been tested on users? If not, why not? (Are these the right requirements?)
  • Will users be given the opportunity to provide feedback on these through the development? (And if so, how, when and where?)
  • What user outcomes are we trying to achieve with the release? These may not be requirements that we put a cost on, but an expectation that we can measure against to show improvement – we would need to communicate this appropriately.
    • E.g. minimise clicks to access the 5 main functions
    • E.g. reduce time-to-complete for function x, y and z by 10%
    • E.g. Align existing UI with iOS and Android norms
    • E.g. Increase usage of function z by 5%
    • E.g. 99% AAA compliance
  • Who represents users on the project team?
    • How many user types do we need?
    • Can normal users and administrators share UX, or are their goals divergent? – different apps, different ASP Areas, different branding, …
  • What platforms and form factors need to be supported/tested?
    • Does each platform need a native UX? If native app, probably yes, if web app, maybe.
    • If mobile, do we need to adapt to context : location/orientation/communication with nearby devices/…
    • If social, do we need to adapt to context : can I approve my own work?/who’s online/recommendations/who’s nearby/…
  • Do we, as developers, have any input to the UI design? If not, why not?
  • Have the designs been tested on users? If not, why not? (Does the UI fit user expectations?)
  • Do we have appropriate guidelines for the appropriate platform, and are they listed in the requirements and estimates?

Potentially useful resources


development programming

Working exactly to spec

Is there a problem?

  • The work was completed to spec.
  • Any additional work was likely to break the time and cost estimates.
  • The work meets the current standards. To bring the remaining paintwork up to standard would require removing and re-implementing the solution, further risking budgets and blocking higher priority work.
  • The only available colours do not provide the legacy appearance required to match the existing lines.
  • The blue lines were not part of the original specification and therefore no knowledge is available on their purpose and whether they should be extended or removed.
  • The disjointed yellow line on the right-hand side would require straightening, which would cause confusion to existing users. There are multiple consistent configurations and the workers have no means to evaluate which of these minimises confusion.
  • The user who raised the bug report is unaware of the timetable detailing the repainting plan and the agreed extent of the lines.
  • The user who raised the bug report is unaware of future proposed fixes that will require additional upheaval. Any attempt to fix other line issues now will result in unnecessary rework.
  • The existing pattern does not cover the required scope (see the far side), and any additional work would lead to scope creep to correct this error.
development programming ux

Non-functional requirements and terrific testers

There’s a ongoing debate about non-functional requirements: Non-Functional Requirements Are Not Nonsense and it’s a debate I’ve had within my teams as well.

In most consulting projects I’ve seen, non-functional requirements are listed as a nice to have, rather than a must have. It’s not a matter of business logic vs. performance either. In one rare exception, I’ve had a requirement for an import function to load and validate millions of records within a 48 hour period. If the import wasn’t correct and wasn’t fast enough, the requirement was not met. We made it with room to spare.

I think one of the key problems developers have with non-functional requirements is that they aren’t tasks to be achieved then ticked off, they’re cross cutting concerns, and are often best effort, so don’t need to be 100% complete to be ready to ship. They can be continually refined.

This can be hard for binary developers to grasp. Tests pass or fail, requirements are complete or not. And in a pre-devops world, many of the factors affecting them are outside the control of the developers. You can’t have 99% uptime on a VM that’s off for 30 minutes a day to be backed up.

Good testers help to bridge the gap by turning an aspiration into a target. They hear the customer wants the website to be fast, and they write 95% of requests return in under 250ms. Browser compatibility goes in the test log, because “the current version of…” is a moving target.

Not that we pass responsibility for meeting the requirements from developers to testers, but we get the testers to turn something vague and system wide into something tangible and testable that the business owners and developers can agree on. After all, if it can’t be tested, there’s no way to measure of it’s done.

Most of all, it’s about explaining to business owners that an aspiration is not a requirement.

development test

Your API sucks : testing

Finally, you’re ready to launch, you’ve integrated the API, you’ve decoded the documentation, you have passing integration tests, and FAT passed against their test server, with their test data. You go live. And everything breaks.

Strawman testing

Sometimes the test data or the API out of sync with live, and you find you’ve been testing the wrong thing. Maybe the test server is a version ahead of the live API (if they’ve ignored the advice not to version HTTP APIs).

More frustrating is when the data is plain wrong. When the returned record has { Firstname = “Lincoln”, Lastname = “Abraham” }, or an invalid postcode (did you know, The final two letters do not use the letters CIKMOV) which means the test site may require a postcode that your validator will reject.

Tests doomed to succeed

Sometimes the test data is correct, but incomplete. Imagine a postcode lookup where test addresses are all SW… which means you can’t test for:

  • Flat x/y addresses
  • BFPO addresses
  • Irish or other EU addresses

Or imagine a payment processor test stub that always returns success – so you can’t test for declined cards, or 3DS cards, or check that you only accept debit cards.

If your API supports it, put it in your test, and make it available to users for their tests. If it’s not tested, it’s not complete.


development programming security ux

Cognitive load: Default to success 

​Process impedes progress. It’s the hurdles, and the red tape, that stop you from doing what you want to do. It’s why you can’t have administration rights on your machine, it’s why you can’t commit directly to master. It’s why developers don’t get logins to production. It limits your agility. 

Sometimes that’s a good thing. So long as it’s a straightforward, time efficient workaround. You don’t commit directly to master, but every green, code reviewed pull request does. You don’t get a login to production, but the deployment server does, and you can quickly get access to production data on your machine when required to recreate a bug. And your live servers are protected. 

Make it easy to do the right thing. Process is part of it, and so is tooling. Don’t make me think about the right way to do it, direct me, without getting in my way. Make the process implicit, but open for investigation and improvement. 

We believe in people over process, but when machines can automate the process, the people are free to think about the business problem.


Paperless and warning free

there's a dog driving that car?
Do you have a licence

As a quick follow up to my post on the new process for endorsements following the demise of the paper counterpart driving licence.

First, a clarification, the change in the DVLA is for the paper counterpart to the photo id licence, not the paper licence that existed before the photo id licences. Many people will have been switched to photo id by moving house though, so it’s only the hardcore who won’t be included.

I got confirmation from the car hire firm 24 hours in advance that I needed to print out my endorsements sheet, by which point I no longer had access to a working printer, so I was glad I’d tried it beforehand. The guy at the desk noted that it was a new scheme, and also mentioned that if I hadn’t printed it out, they would need to call a DVLA verification phone number which is very busy when it’s not shut. So still a number of teething problems to sort out.

Do if you are hiring a car, get yourself over to dvla in advance (any time within 21 days) and get your endorsement sheet printed. It might just save you from long queues and grumpy car hire staff.

code development programming test Uncategorized

Apprentice programmer

unlit olympic flame

Let’s talk about plumbing, and customer service, and an experience I had recently with a company I won’t name. Overall the experience was good, but I don’t want anyone to get into trouble because they’ve misinterpreted what I have said here. (and if you’re wondering about the picture : the Olympic flame isn’t lit either).

A couple of months ago, our gas combination boiler failed. It refused to start and complained that the flue was blocked. I sighed because we’d had the bearings on the fan replaced last year. So I called the service company to get it fixed.

A couple of days later, I was working from home to let the service technician in. He was fairly young but identified a problem. Unfortunately, a new part was required, so he had to come back the next day. He came back, replaced the part, fired up the boiler and all looked good. The next morning, no hot water and a flue warning 😦 it was the weekend by this point so we got a senior employee, who identified an error in the replacement part (fitted the wrong way) and identified the original problem as a blocked inlet. 5 minutes to identify, 1 hour to dismantle the boiler to get to the blockage and put it back together.

He finished, switched the boiler off, and then made sure it fired when put back together. Problem solved.

So, what did I learn, and why am I posting this on a programming blog?

Firstly, a monthly fee means that I didn’t have to worry about callout or parts, which was great, and left me less annoyed than I might have been.

Secondly, your first fix might not be the right fix. It looked right and it passed the first test, but caused problems later on (at the next restart). Ever written the wrong test and thought the problem was solved? Threading has caught me out in that way before.

Thirdly, just because it passes the test, doesn’t mean the problem is fixed. The boiler fired easily when the case was open and there was more airflow, but didn’t fire when the case was closed. Ever had a bug that only appeared in production or in a system test?

Fourthly, experts will find problems quicker than rookies, but rookies still need to learn.

Fifth, sometimes the only way to fix a problem, even a small one, is to tear everything apart, blow on it, and put it back together again.

The second guy also said something that struck a chord, as I’ve been trying to do it myself : he was disappointed that the company didn’t send the junior out with him so he could pass on his experience so that he’d learn for next time. Apparently, the fault itself is rare, so it’s a good learning opportunity. For developers : fix your own bugs, as there are a lot of things apprentice developers will see in the first few years after they graduate that are rare enough not to come up in university but common enough to be real problems in the real world. For example,
trusting user input (and the related buffer overrun bugs).

So, what have you learned from other professionals?

code programming

TDD? I Don’t Have Time – Google Docs

TDD? I Don’t Have Time

Thanks to everyone for their feedback on my previous post. I’ve taken the next step and created a presentation that’s publicly available on Google Docs via the link shown below. I’ll be adding more ideas to it as I get them, and I may do a small coding demo if I’m feeling brave.

As before, add comments below, or send feedback to the twitter account or email address in my previous post.

TDD-I-dont-have-time – Google Docs

Blogged with the Flock Browser
code programming

Test Driven Design : Developer Day Scotland 2

TDD? I don’t have time

I’ve had one of my talks accepted for Developer Day Scotland: talking about Test Driven Design. I’ve got a basic idea for a talk, but in the spirit of Alt.Net and open source development, I thought I’d throw this important subject out to the crowd. I’ve got a few ideas for the talk that I’ll outline below, but I’m looking for ideas and stories from others to help illustrate this point. Lest you think this is the easy way out, remember that I’ll be editing, compiling and delivering the talk, and I’ll get all the hecklers and tricky questions.

In return, I will release the presentation under a creative commons licence so that anyone else can take it, adapt it, and use it to help sell the principles of TDD to their colleagues. I’ll also make sure all contributors are included in the acknowledgments, provided they give me their name. If you want to give feedback, comments below are preferred as they’re public, but you can also send them to me via twitter ( @craignicol ) or via my gmail address (which I won’t give here to avoid spam harvesting, but it’s the same username as my twitter account)

The basic structure of the talk will be a series of slides titled with a reason not to to TDD, followed by a few suggestions why that reason is a myth, or is not as big a problem as you might think. Based on last year’s DDDS, I expect most of the audience will have come across unit testing, but I might need to add that to the sales pitch. I’ll list below the basic ideas I’ve got so far. Any arguments, expansions, examples or other feedback gratefully received.

I don’t have time

  • Do you have time to debug a live system?
  • Do you spend time adding new features?
  • Do you have the right tools?

I don’t need to test

  • Are you a perfect programmer?
  • Are you working alone?
  • Will you ever maintain your code?

I need to know about IoC, mocking, etc

  • Not when you start
  • Don’t let the terms scare you, it’s the principles that are important
  • The principles are worth learning

I love TDD, but I can’t get my team to adopt it

  • Don’t keep it to yourself. Show it off.
  • If you’re the lead, make it happen. CI is your friend.

I don’t know what tools to use

I need 100% code coverage

  • Have you been talking to Joel?
  • You don’t need 100%, but until you try and reach it, you don’t know what you don’t need.
  • You have to decide which of this, and many other aspects you feel comfortable with, and which you don’t.

Quality doesn’t matter

  • It matters to the customers who have to wait longer for a working product
  • It matters to the developers who have to maintain your code and will leave or stop caring
  • It matters to the accounting department who lose money for either of the above

You can’t test a UI

  • Make sure your logic can be tested without a UI
  • Test the right thing on your UI
  • There are frameworks (NUnitForms, WatiN)
Blogged with the Flock Browser