Useability issues

One of the reasons why Borland products tend to score above the microsoft equivalents is in the area of  small usability touches.

The .NET Framework has a LinkLabel control. The purpose of this is to allow hyperlinks &c.
However there is no desgner for this. You have to add the associated links in code.
While this is flexible it is more difficult than necessary to use for the simple case. Borland would have implemented the designer here.

Borland’s big problem has been marketing and sales.  Even when they have a superior  product they  cannot get the market to accept it.  Of late they seem to be diversifying into earlier stages of the lifecycle – requirements (CaliberRM), design (Together and Bold) and configuration/planning (StarTeam). It is difficult to complete against the Microsoft Universal licence (allowing access to almost all the development tools for a fixed annual fee) – Microsoft make their money off of the server products that the customers require. Borland could launch a product as a Visual Studio extender – adding in the missing property editors.

Microsoft Documentation

The .NET framework is surrounded by a lot of documentation.
However a lot of it leaves much to be desired.

There is a classic joke about a helecopter pilot that is lost in fog in Seatle.
He hovers near an office block and shouts out “Where am I?”
Upon hearing the answer “You are in a helecopter” he knows that he is at
Microsoft HQ’s documentation department and is able to fly diretly back to the
airport. The answer being both entirely accurate and completely useless.

This is a classic example. I have been trying to find out the purpose of
the EditorBrowsableState.Advanced option.

The documentation reads:

The property or method is a feature that only advanced users should see. An editor can either show or hide such properties.

This is again entirely accurate but completly useless.

The sample code that is linked to uses the EditorBrowsableState.Never option.
Why document the obvious case?

More Missing Stuff

Moving from the Delphi IDE to Visual Studio can be very frustrating.
While VS.NET is a real combine harvester in that it can perform a wider range of editing
than the Delphi IDE it seems to be lacking in some basic smarts that were in Delphi 1 ten years ago.

In Delphi when you rename the main form the equivalent of Application.Run is automatically updated. This may be a small thing but unless you want every app to have Form1 as it’s main form this is going to get rather old very quickly.

In Delphi when you leave an event handler empty (no code or comments) and build then the IDE removes it from the event handlers of associated objects. When you rename a control that has an event handler named after it the event is renamed and all of the IDE linked references are updated. If you have coded against it you need to fix these up yourself.

These are small things, but do grate.

Real World Unit Tests

Theoretically all of your code should be covered by unit tests (although it is common to ignore simple properties). For help with this see NCover hopefully this will soon get a VS.NET addin.

If you are really lucky you are working on a greenfield project that has clear static requirements, a simple yet detailed design document, a full set of acceptance tests and plenty of time to write the unit tests. However in the real world you don’t have any of these.

Typically you will have an existing code base, some of which is covered by unit tests and the others not.

You need to prioritise where to write the unit tests.

Carefully constructed tests can excercise a large part of the system in a few tests.
For example if you use a Facade to import data into the system (considered an atomic step, but actually exercising a lot of validation, parsing and persistance code) you can exercise the most frequently used 25% of the system in a handfull of tests.

If a test fails you can use other smaller more detailed tests to narrow down the error.
The only downside to this is that a single error in a fundamental system can cause hundreds of failures.

If one area of the system has failed frequently over a number of builds then it is an obvious target for some new unit tests.

If any area of the system includes scripting, dynamic sql  or stored procedures they need to be called at least once by the unit tests. This will excercise the database creation script during either the build process or by the Continous Integration server (You do create a new database as part of your build process don’t you?). Anything that is not checked by the compiler is ripe for typos to cause havoc. Stored procedures are great – when compiled they report certain errors (the sql does not make sense) however they can ignore the fact that tables or fields do not exist.

Tests need to be fragile with respect to the functionality tested, but be immune to minor changes in call symantics. This is where some simplifying Facades really help – they isolate the test code from change, encourage reuse, make the test code easier to read and can provide ideal debugging fodder (either after the test has been run or set breakpoints and run a single test).

Most useful XP Idea

XP is a collection of development practices that can if used in concert speed up application development in the face of changing requirements and most of the time requirements change. Some of the practices are there to cover for weaknesses in the other practices, for example refactoring is dangerous without detailed unit tests.

If you want to ignore most of the XP practices the best to adopt would be the automated unit tests. These are developer tests, not formal QA acceptance or regression tests. Things that should be tested here are that the stored procedures actully exist, that they run with typically data without catastrophic failures. It is best to think of these as a replacement for asserts.
(Personally I replace any assert that will stop program execution with an equivalent exception – this makes it far more friendly to a unit test.)
An assert will warn you that an error condition occours while a unit test demonstrates what happens when the error condition occours.

There is a problem with the typical gui unit test addins – they write one stub test per public or protected method. This creates lots of almost irrelevent tests. The best way to think of unit testing is in terms of  testing buisness functionality. This allows unit tests to be used as documentation of buisness scenarios. Plus if you omit to reset your database in the teardown (and always reset the database in the setup) then you have the oppertunity to have a tested buisness scenario that can be used as the starting point for manual UI testing. This technique alone saves hours of debugging time – write a test to recreate the exact condition that you are looking for and if you go one line too far in the debugger and destroy the test condition it is usually a matter of seconds before you can recreate the exact data that you were using.

Automated Unit tests become especially valuable when you are working across multiple streams of development. The project I am currently working on has 4 current development streams (one pure development plus three live customer streams). Since these are slowly diverging (certain new features only get added to the later streams – fixes to those units in older streams cause divergence) a fix or enhancement may need to be implemented in several places.

Tests need to be focused (test one functional area) and atomic (failure of one test should not stop the system).  It is fine (even preferable) to use parts of your system to setup tests for other areas.The test framework that I use has a set of Facades that abstract away parts of the system and uses them to simplify tests. 

For example if your system delt with processing customer orders (these arrive as XML documents) you could write a Facade around the code that parses and stores the incoming document and use other classes to generate the data.

So the start of the test would be:

    TOrderImporterFacade.ImportOrder( TSimpleOrder, 100, ‘FooBar’ );

This would use the class TSimpleOrder to create a order for 100 FooBar’s

You could then check the outstanding orders

   CheckEquals(100, TStockFacade.OpenOrdersCount(), ‘Before Restocking’);

Use another Facade to perform the buiness functions.

   TBuisnessFacade.Restock();

And again peform the same check.

   CheckEquals(100, TStockFacade.OpenOrdersCount(), ‘After Restocking’);

This technique is less fragile with respect to functional changes, the tests are far easier to read,
and it is very easy to add a new buiness scenario as an experiment.

XP Values, Practices and Principles

Here are the XP

Values:

  • Communication (possibly Visibility)
  • Simplicity
  • Feedback (formerly Testing)
  • Courage (formerly Aggressiveness) (See: XpCourageValue)
  • Respect

Practices:

Principles

Fundamental Principles:

  • Rapid Feedback
  • Assume Simplicity
  • Incremental Change
  • Embracing Change
  • Quality Work

Further Principles:

  • Teach Learning
  • Small Initial Investment
  • Play to Win
  • Concrete Experiments
  • Open, honest Communication
  • Work with people’s instincts – not against them
  • Accepted Responsibility
  • Local Adaptation
  • Travel Light
  • Honest Measurement