Goodbye

May 31st, 2011

Just a quick note that I’ll be decommissioning this site at the end of June, 2011. Please archive any articles you found interesting or useful.

Best of luck to you all.

XP

GUI testing with DUnit

February 2nd, 2009

I don’t how I didn’t know this until now but it turns out there’s a whole section of DUnit designed to help you test GUI elements. What follows is small write up about how to do it. Read more…

XP , , , ,

The value of knowing value

January 19th, 2009

Figuring out what to do next or even where to start is alway a challenge.

Scrum and XP both have an iteration planning method in which the team gives each unit of work (story) an estimation of effort. We typically call these story points. Story points are essentially an order of complexity against a baseline story.

The typical format is the Product Owner brings stories to the Team for estimation. The Product Owner and Team talk about each story until the Team feels comfortable giving an estimate. In the beginning of the iteration the Team decides how many story points they can get done and the Product Owner lines up the stories in priority order/ The team then pulls into the iteration as many stories as will fit based on the sum of the story points.

Teams will carry on like this using the sum of the story points they complete in each iteration as a measure of their productivity. Increasing this measure of productivity, called Velocity, is supposed to be a sign of a team getting better and delivering more business value each iteration. This is where I think we mess up: equating velocity with business value.

Read more…

XP

RE: Architectural Hedges

January 7th, 2009

Craig Stuntz recently posed the question of how to build hedges into our products and processes.

If I understand the problem correctly what we want is a way to mitigate the risk of choosing the wrong technology or technique. This is to say if we do choose the wrong technology or technique (for whatever reason) how do we recover and change direction with a minimal amount of fuss and cost.

I think the biggest guiding princple we have for this is Deferred Implmentation. Deferred Implementation demands implementation agnosticism from the client code. We’ll use the User Repository code from the post Keep you code lazy and ignorant as an example. When we wrote the code that needed to look up a user by the user name the client code was ignorant of how the data got there. This was good because it meant we could focus on the business logic of logging in and leave the details of how retrieve user information for later. All we needed to supply was an API for the client code to use. Later, in the next post, we wrote the code to retrieve the user data using an ADO connection to a SQL database. The truth is we could have used any storage medium like an XML file or web service. Either way the client code didn’t change because of the implementation details in the User Repository. Doing this created a hedge in both the barrier sense and the risk mitigation sense.

TDD played a big role in getting to the deferred implementation of the User Repository. We were able to quickly put together a test bed for our ideas and keep it to be sure we didn’t inadvertently break anything. TDD also gave us a formula for the incremental improvement of the code.

TDD by itself didn’t get the job done. We needed to be conscious of separation of concerns, not mixing object creation with business logic and design patterns that help us solve these sorts of problems.

I hope this addressed the question Craig posed. If not, I hope this was at least informative.

XP , ,

The big cup problem

December 29th, 2008

It’s a strange thing about a big cup … or any large container for that matter. When you see it empty your immediate response is to fill it up. What can I put in here? There’s still some room in here, how can I use it? When you pull out a cup from your cupboard to take a drink you almost always fill it up.

I’ve found myself lately writing code to solve a problem, looking at the volume of code and being upset over how little of it there is. I think, “Wow, I really wanted to solve a big problem. This code works but I can’t use it because there’s not enough here to match up with the magnitude of the problem!”. It’s like buying expensive software that comes in just a CD case. We shell out big bucks and only get a CD in a jewel case? No, no, no; I want to feel like I got my moneys worth!

How often do we do that? We start with this big cup and try to fill it up. We write more code than necessary,more tables than needed, more infrastructure, more text in the blog post, more, more, more.

The problem isn’t the work or the stuff; it’s the cup. We start with a big cup and try to fill it. Start with a small cup. If it overflows then great! Get a bigger cup.

It’s okay to get stuff done with less. Less code, less effort, fewer hours. Scale it back. Pare it down. Do just the bare essentials and do them exceeding well.

Heres to a new year of smaller cups. Happy new year, all!

What we need, XP

Get faster with FitNesse

December 1st, 2008

This is the third article in a series beginning with Busting the great TDD myth and Keep your code ignorant and lazy. If you haven’t already read these articles I recommend checking them out as I will continue to use the same code as an example.

In the last article we looked at using the Provider pattern to make a flexible data access layer. It allowed us to test our TUserRepository in isolation even though it is dependent on data. Lets breifly review that code:

type
  ILoadable = interface
    procedure AddRecord(const UserName, Password : string);
  end;
 
  ILoader = interface
    procedure Load(Target : ILoadable); 
  end;
 
  TUserRepository = class(TInterfacedObject, ILoadable)
  private
    FUsers : TStringList;
  protected
    procedure AddRecord(const UserName, Password : string);
  public
    constructor Create(Loader : ILoader);
    destructor Destroy; override;
    function Lookup(const UserName : string) : TUser;
  end;
 
  TTestData = class(TInterfacedObject, ILoader)
  protected
    procedure Load(Target : ILoadable);
  end;

By having TUserRepository implement ILoadable and creating a stub for loading test data called TTestData we were able to write a test like this:

procedure TUserRepositoryTests.SetUp;
begin
  TestData := TTestData.Create;
  FRepo := TUserRepository.Create(TestData);
end;
 
procedure TUserRepositoryTests.TestValidLookup;
var
  user : TUser;
begin
  user := FRepo.Lookup('fred');
  CheckEquals('flinstone', user.password);
end;

What’s good about this arrangement is that we’ve tested the business logic of TUserRepository independent of a data source. However we’re left the question of how to write and test the actual production code that will provide live data to TUserRepository. We could test-drive this code in a unit test but the rules of TDD tell us that a test should not need external dependencies. Also, accessing a database in a unit test would slow down the test suite. So how do we test this code?

Read more…

XP ,

Keep your code ignorant and lazy!

November 26th, 2008

This post is a follow up to Busting the great TDD Myth. If you haven’t already read it, please check it out.

Lets review the code from the last post:

function TLogin.GetConnectionString : string;
var
  reg : TRegIniFile;
begin
  reg := TRegIniFile.Create('Software\MyApp');
  Result := reg.ReadString('Database', 'ConnectionString', '');
  FreeAndNil(reg);
end;
 
function TLogin.Execute(const UserName, Password : string) : Boolean;
var
  UserQuery : TADOQuery;
  DBUserPassword : string;
begin
  UserQuery := TADOQuery.Create(nil);
  try
    UserQuery.ConnectionString := GetConnectionString;
    UserQuery.SQL.Text := 'SELECT Password FROM Users WHERE UserName = ' + 
                         QuotedStr(UserName);
    UserQuery.Open;
    DBUserPassword := UserQuery.FieldByName('Password').AsString;
    UserQuery.Free;
    Result := DBUserPassword = Password;
  except
    Result := False;
  end;
end;

Now lets review the problems:

  • Hidden dependencies - TLogin does not publish the fact that it relies on a connection to the database and needs a connection string from the registry.
  • Mixing concerns - Business logic and object creation occur in the same block of code. This means you can’t test business logic without creating the dependencies.



All of these problems can be summed up as: Too much ceremony and too little essence. What is this class trying to do? Does creating a connection to the database, querying a table and handling exceptions have much to do with the purpose of logging in to the system?

Read more…

XP , , , ,

Busting the great TDD myth

November 20th, 2008

WARNING
There’s a lot going on in this article. It is intended to be humorous and slightly inflammatory. It’s also the first of a series. I intend to show you how the average Joe digs himself into a hole and then how to get out. I hope you enjoy the read.

On with the show …

You will not learn what you need to know from a TDD course/book/lecture. When you walk away you will not be able to write better software. You will not be able to test drive all your code in a fully automated test suite. Your expectations will not be met and you will quickly dump the whole concept of Test Driven Development.

It’s true.

The problem has nothing to do with TDD. The problem is that you don’t know how to write better software. TDD will not make you a coding rock star. You will not be the envy of your peers. Your face will not be printed on a t-shirt (I don’t think that’s ever happened but it would be cool).

Read more…

XP , ,

Science without art is no fun

October 9th, 2008

I just encountered a great article on Ward Cummingham’s wiki. It’s called Programming Is Not Fun. The section that I enjoyed is called “Programming Is Not Fun without Philosophy”. You can find it near the bottom of the page.

I’ve always considered programming/engineering/development to be more art than science. I guess you can chalk it up to my background in the arts. What hit home for me was the assertion that any kind of work done without an underlying philosophy is wicked boring and unfulfilling.

The article notes that other arts have established and accepted schools of thought and philosophy. For instance, painting has Cubism, Impressionism, etc. Do we have schools of thought and philosophy? Do we have Waterfall, Agile, Do-Whatever-It-Takes-To-Ship, TDD, BDD?

What about you? Do you employ any sort of philosophy in your work?

XP , , ,

FitNesse for Delphi updated

September 25th, 2008

Thanks to Michal Wojcik for completing the port of FitServer to Delphi. Going forward you can get the code from http://code.google.com/p/fit4delphi/.

All the major fixtures have been ported (Column Fixture, Row Fixture, Action Fixture, Table Fixture, Row Entry Fixture).

What does this mean to you? Check out The Need for Automated Acceptance Testing. FitNesse is a tool created to fit this need (no pun intended).

What’s great about automated acceptance testing? In short: concrete examples straight from the customer. FitNesse is also a way to get executable specifications. FitNesse does its work in the form of a wiki. You can organize tests into hierarchal test suites that are editable the way any wiki is. This provides a familiar and friendly interface for non-technical types. All of this adds up to an environment in which tests can be written and organized in such a way that they specify desired functionality before the code is written and serve as documentation after the fact. No more having to interpret written specs into tests and production code.

It takes some training both on the developer’s part and the customer’s part but it’s well worth the effort.

XP , ,