Wednesday, 14 October 2009

Kanban Blog

Having leapt aboard the Kanbandwagon, I've started a new blog about Kanban at, funnily enough, Here's a taster of my first post:

Which of these feature ideas should we select as a priority?

Feature Estimated
Production Time
A $100,000 40 hrs
B $80,000 40 hrs
C $60,000 40 hrs

Feature A? It's a no-brainer, right?

Not necessarily...

Monday, 25 May 2009

Concordion 1.3.1

Concordion 1.3.1 was released last month with a handful of new and noteworthy features. There was an announcement on the Yahoo mailing list, but I wanted to wait for the Concordion.NET port to catch up before making an announcement on this blog.

For those who didn't know, there are now versions of Concordion for:

So, if you're using Cucumber in Ruby, or FitNesse in .NET check out the alternative. No other acceptance testing framework lets you create such readable acceptance tests as Concordion's. The key advantage in having readable tests is that when you come back in three months time and wonder what the heck you were doing, you might actually have a clue.

Update: Jeffrey Cameron has started a blog about Concordion.NET and how to use it.

Thursday, 19 February 2009

Avoid not using positive method names

I'm integrating with Spring Security at the moment. It seems to be a well-designed framework, but I got myself confused this morning trying to implement some methods of the UserDetails interface:

boolean isAccountNonExpired()
    Indicates whether the user's account has expired.
boolean isAccountNonLocked()
    Indicates whether the user is locked or unlocked.
boolean isCredentialsNonExpired()
    Indicates whether the user's credentials (password) has expired.
boolean isEnabled()
    Indicates whether the user is enabled or disabled.

I imagine the designers wanted all the answers to be true for the normal "happy" situation. But my brain couldn't cope with all the negatives, so I ended up writing a second set of positively-named methods to call from the negative ones. :-)

public boolean isAccountNonExpired() {
return !isAccountExpired();
... etc.