TeamCity 1.2 from JetBrains just released – level 200

From the name’s similarity with Microsoft’s TeamSystem, I thought JetBrains might be trying to compete with Microsoft in the team collaboration arena.  They might be still, but TeamCity 1.2 is definitely a continuous integration server. 

JetBrains is well-known from their excellent IntelliJ Idea Java IDE as well as their Resharper add-in for Visual Studio 2005.  In fact yesterday at the local AgileATX lunch, Scott Bellware and I spoke about how much we actually develop in Resharper more so than in Visual Studio.  Resharper replaces the Visual Studio experience with a better developer experience. 

JebBrains originally targeted TeamCity to Java developers, but that was because they only had plugins for Java IDEs.  With TeamCity 1.2, they have completed an integration plugin for Visual Studio that allows integration with the TeamCity server from the workstation. 

For those of you who use Team System (or wish you could afford it), note that TeamCity is a continuous integration server at this point, not a project management server or work item tracking server.  TeamCity is competing directly with Thoughtworks open-source project CruiseControl and CruiseControl.Net.  You can see a comparison they have done between the three.  In the comparison, they appear to have many more features, but none of the “missing” features from my CCNet are compelling enough to make me want to switch at the point.  Most of the features are really provided by the NAnt script anyway, not the CI server.  You can watch an online demo on their website.

TeamCity is a new product, and I intend on following it as it grows more mature.  JetBrains is known for quality software, so there will be some interesting things to come, that’s for sure.

Having a baby and an integration testing tip – level 400

I found out today that my wife is with child, and we're having a baby!  Now, on with the post. . .

 

Integration testing isn't your basic 200-level topic at an MSDN event.  It can be very involved.  I believe that a good integration test has to depend on targeted unit tests being present.  Consider the scenario without unit tests:

Bob has a use case that spans 15 classes.  He sets up the environment to get this slice of the system under test.  He then proceeds to write the test with asserts.  He quickly becomes frustrated because for each of the 15 classes along the way, there are different scenarios that are possible.  If each class has just 2 possible uses, his number of scenarios to test are 2^15.  Each scenario requires many assert statements.  Faced with 32,768 test combinations, Bob is disgruntled and concludes that automated integration testing is too much overhead.

What did Bob do wrong?  First, Bob attempted to start his automated testing at the integration level.  Second, he assumed unit test responsibilities inside the integration test.  Third, he tried to test every possible combination of integration.  Fourth, he hadn't surrounded himself with a quality team that could help guide the testing strategy.

Here's the success scenario:
Bob has written unit tests for each of his 15 classes.  He marvels at how simple they looks since each unit test only has to cover 2 usage scenarios for each class.  With confidence that each individual class will do its job correctly, Bob writes an integration test for the use case choosing one of the many combinations that could occur.  Bob sets up the test, executes it, and then asserts on the resulting state of the system.  Bob finds an integration issues caused by how two of the classes interact with each other.  He fixes that bug, and the test passes.  Bob now has confidence that the 15 classes are interacting properly in his use case.

 

If you haven't already read the following from my friend, Jeremy Miller, take a minute to do so:

Qualities of a Good Unit Test: http://jeremydmiller.blogspot.com/2005/05/qualities-of-good-unit-test.html
Achieve Better Results by following Jeremy's Third Law of TDD: Test Small Before Testing Big: http://codebetter.com/blogs/jeremy.miller/archive/2006/05/30/145752.aspx

The first task of a new software project is to build trust – level 300

Please read this post by Brad Appleton (and some links off the post) about building trust in a software team.  The notion is very profound, and we don't talk about much in professional circles.  I, for one, can easily be drawn into only thinking about the technical aspects of software development.  It's easy because it's something at which I excel.  Years ago I went so far as to scoff at a previous employers attempted evaluation of "soft skills", but I know see the importance of it.  Technical skills are necessary, but the greatest techy on earth can be rendered ineffective if no one will trust him.

Importance of developer data – level 200

Most of my experience has been with systems that require a relational database to house most of the data.  Some systems have used a combination of relational databases, files, and external sources.  Regardless of the data store, there are different ways to set up the data stores in a developer environment that affect the ease and speed of development.  For clarity, I am talking about the database that is used by every developer on the development workstation (not a development team staging server)  I’ll start with the worst way.

Use last month’s production backup (BAD)
Assume for a moment that there is not a single corrupt field in your production data.  Even so, the data set can be so large that it is tough to see clearly what is going on while developing locally.  While working out problems in the program’s behavior, it’s necessary to peek into tables to see what data is there, and with a full production set, the developer has to formulate queries merely for narrowing the scope of the data to view.  Using a full production set bogs down development with unnecessary overhead.  Finally, it will be very hard to create repeatable tests since the developer is constantly changing the data.

Create a development database with fake data and put it on a shared server(BAD)
The “shared server” part of this one is the killer.  Imagine running a scenario using this database, and the data changes.  With a shared database, this is what happens.  Multiple users changes the data in many different ways.  A high degree of communication overhead and waiting is required to make this work.  The fake data will need to be refreshed periodically, so it becomes necessary to stop the team from using the database during the data reload.

Use a local database with nothing in it(BAD)
This is probably an obvious one since the system probably won’t function without a proper data set.  If it will, security or configuration problems might lurk in the shadows (if you have security or configuration tables). 

Use a local database created with the local build and populated with representative data that is enough to support every use case in the application(GOOD)
In your local build script, have a target that creates the database locally from scratch.  Have a routine that pumps data into this local database.  In this data set, include enough data so that every use case in the application can be exercised.  As functionality grows, add to this data set proportionally.  Structure your automated build in such a way that it is easy to:

  1. Blow away the database and recreate it from scratch.
  2. Blow away the database and refresh it at any time.
  3. Create multiple local databases in the same way with different names.

Your automated database tests are going to be blowing away and reading data in the normal course of execution, so it’s important to be able to refresh the database at any time.  Using this technique, you will be able to run the system locally at any time and use it in a representative manner (and debug if necessary).

WHAT ABOUT A TESTING DATABASE?
That’s a different animal.  You want the testing database to make bugs obvious.  Another tricky thing is that there isn’t just one testing database, so that’s a topic for another time.

I’ve been tagged. . . and enumerated classes – level 200

After being tagged my numerous people, here's my 5.  My
long-time readers might know some of these if they've been reading closely over
the past few years, but here are 5 things about me that aren't widely known:

  • In college, I was a member of the Texas
    A&M country & western dance team:  www.aggiewranglers.com – I got to travel
    the country and world performing c&w dance.  I married a girl who was also
    on the team. (all partner dancing, people, no line dancing).  Think "girl being
    thrown in the air".
  • In 2003 I was
    called up for Army service to Iraq – was there 1 year and 3 days.  I'm 1.5 months
    from separation, so I'm hoping the nothing BIG happens between now and March
    3rd.
  • I was using Yahoo before it had
    e-mail service, and my account is one of those that is really jacked up because
    my id I originally registered had to be an e-mail address.
  • I started writing database web applications
    before the dawn of ASP 1.0 – Anybody remember .idc and .htx files? – My CGI work
    was configuring WODA for a few clients.
  • When I was a kid, I read every book on
    motorcycles/dirtbikes/ATVs in the public library, and I'd moved on to the adult
    section.  I was the only young kid who knew the difference between a two-stroke
    and four-stroke engine.  I now have a motorcycle, love to ride dirtbikes, and I'm
    lobbying my wife for a Harley.

Now, I'm going to tag Scott Bellware 5 times.

So
that this post is now void of technical content, here is a tip for using
enumerations in your applications:

Consider the following class: 

    1     public class WorkOrder

    2     {

    3         private Status
_status;

    4    
    private string _description;

    5 

    6         public Status
Status

    7    
    {

    8    
        get { return _status; }

    9             set { _status = value; }

   10         }

   11         public string
Description

   12         {

   13             get { return
_description; }

   14             set { _description = value; }

   15         }

   16     }

Notice that we are using a
Status class (enum):

    public enum Status

    {

        Pending,

        InProcess,

       
CompleteNApproved,

    }

My system manages work
orders.  Realize that this is an over-simplified example, but what happens when
you need to list our many WorkOrder(s) in a grid or for a printable report? 
Easy, right?  No.  You have this Status property that is very ugly when
displayed.  "InProcess", "CompleteNApproved".  Your users don't want to see
that.  In business speak, it needs to be displayed as "In-Process", and
"Complete & Approved".  How do we do this easily in code?  On possible way
is to create a Facade class that is used in reports.  This facade class could
translate the enum to our required Status titles.  This is undesirable because
we then have to wrap each WorkOrder instance in a new class just for display
purposes.  I would prefer that our WorkOrder could be displayed on its own, but
we have to do something about that enum.  Let's turn our enum into an enumerated
class:

First, I'll rename the enum like so:

    public enum StatusValue

    {

        Pending,

       
InProcess,

        CompleteNApproved,

    }

Then I'll make Status a
class with 3 static instances: 

    public class Status

    {

        private static Status
_pending = new Status(StatusValue.Pending, "Pending");

       
private static
Status _inProcess = new Status(StatusValue.InProcess, "In-Process");

       
private static
Status _complete = new Status(StatusValue.CompleteNApproved, "Complete & Approved");

 

        private StatusValue _statusValue;

        private string _displayTitle;

 

        private Status(StatusValue statusValue, string displayTitle)

   
    {

            _statusValue = statusValue;

            _displayTitle = displayTitle;

        }

 

        public StatusValue StatusValue

        {

            get { return
_statusValue; }

        }

 

        public string
DisplayTitle

        {

   
        get { return _displayTitle; }

   
    }

 

        public override
string ToString()

   
    {

            return _displayTitle;

   
    }

 

        public static Status Pending

       
{

            get {
return _pending; }

        }

 

        public static Status
InProcess

        {

       
    get { return _inProcess; }

   
    }

 

        public static Status Complete

       
{

            get {
return _complete; }

        }

    }

Notice that I've overridden the ToString() method
so that my _displayTitle field is returned.  Now, when I throw my WorkOrder
class (or List<T> of instances) into a grid or some other binding
container, I'll see the proper display title for my Status.  Now my users are
happy, and I can move a WorkOrder class around anywhere in my application.  For
persisting to the database, I use the StatusValue (which can be Int32, Int16, or
byte) in my database table.  It's easy to do that whether I'm using a
hand-crafted SQL statement or (my favorite) NHibernate for my ORM
solution.

Our lack of built-in enumerated classes is something I plan to
gripe about at the up-coming MVP Summit.  Our enum construct is very weak and is
no more than glorified primitives.  Consider what Java has as of version 5
(taken from http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html):

public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7),
PLUTO (1.27e+22, 1.137e6);

private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double mass() { return mass; }
public double radius() { return radius; }

// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;

public double surfaceGravity() {
return G * mass / (radius * radius);
}
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}

Now we need to play catch-up again.  If in C# I was able to declare my
Status enum like this, I could give it a friendly display title and even some
methods right there in the enum definition.  I would have less code to maintain,
and I would get the build in enum behavior for free.

MVP Summit – Party with Palermo – level 000

For all you MVPs out there, I'll be at the MVP summit in March, so count on a "Party with Palermo" the night before everything starts up.  I'll post more details (time/place) as it gets closer, but since tomorrow many people will be making travel plans, plan on arriving the day before the summit so you can Party with Palermo.

Past Party with Palermo(s) posts: