Announcing Windows Developer Power Tools

Jim Holmes and James Avery have announced their book Windows Developer Power Tools.  I was lucky enough to be asked to contribute an article on CI Factory titled Easing the Burden of Implementing a Continuous Integration Process with CI Factory.

Chapter 12 Build, Continuous Integration, and Deployment

Introduction

Creating Consistent Builds with NAnt

Automating your Build Process with MSBuild

Build .NET 1.1 Assemblies with MSBuild

Extending MSBuild Capabilities with MSBuild Community Tasks

Managing Your Build Process Visually with MSBuild Sidekick

Easing the Burden of Implementing a Continuous Integration Process with CI Factory

Shorten the Development Cycle with CruiseControl.NET

Making Web Application Deployments Easy with Unleash It

Ease Web Application Deployments with Web Deployment Projects

Creating a Setup Project with WiX

 

 Here is a link to the table of contents and a sample chapter:

table of contents

sample chapter

Congratulation Jim and James you have a beautiful baby book.

Build Contention Equation

We are exploring new ways to build our software at work.  I was trying to convey a thought on validating the feasibility of a build process today with the following equation.

Number of Change Packages = 8 Hours * 60 Minutes / (Build Time + Preparation Time + Buffer)

Filling out the right side of the equation will show how many change packages can be process by the build on an average day.  The Build Time is how long it take the build to complete.  The Preparation Time is how long it takes a developer to get the build started.  This could represent claiming the build token, submitting to source control and waiting for the build process to begin.  In the proposed build process only one developer could submit at a time; the build is triggered by a submission to source control.  The Buffer is the tricky variable.  The buffer deals with contention or rather is a means to reduce contention.  It is desirable for developers to be able to submit to the build when they complete a task.  It is not desirable for them to have to wait to submit.  The buffer is the amount of time that will create a situation where when a developer goes to claim the build token chances are it is available.  Let me repeat that, chances are it is available.  I do not know how much this variable should be.  I just see that it is a fulcrum, a way to control, reduce the contention for the build.  It will not eliminate it will just reduce the chances of it occurring.  Lets say we make the Buffer 15 minutes.  This will yield a build that can process on average 20 change packages in 8 hours with a 65% chance that the build will be available when a developer goes to submit.

20 Change Packages = 8 Hours * 60 Minutes/ (5 Minute Build Time + 3 Minute Preparation Time + 15 Minute Buffer)

65% Chance Availability = 15 Minute Buffer / (5 Minute Build Time + 3 Minute Preparation Time + 15 Minute Buffer)

So if you have 10 developers they can submit twice a day.  Does this fit your needs?  No?  Well can you live with a lower chance of availability risking that developers will start working in larger change packages?  If so then lets try reducing the buffer to provide a 50% chance of availability .  That will yield an average of 30 change packages in 8 hours for 2.5 submissions per developer for a 10 developer team.

So what is a team of 10 developers to do if there are no acceptable set of values to this equation?  The only solution that I can fathom out is to split the build into multiple builds (e.g. a build for the client and a build for the server).  Dividing the build should occur along two axis, package dependencies and number of contributing developers.  For example there is not much benefit to splitting the the server off into its own build if only 10% of the team works on it.

kick it on DotNetKicks.com

Testability

What is testability?  When we look at a test subject what is the criteria it that we use to judge it?  What makes us say that needs to be refactored?  What makes us say that is easy to test?  I am sure that there are a finite set of rules that we use to measure testability.  I would like to raise them out of instinctive and subconscious thought and into conscious thought.  To do this we need to back all the way up to sense and control.  These are the two most basic tools of testing.  To test something you must be able to control it and sense what it did.  This implies that there are two main axis that we judge a subject on for testability: controllability and sensabiltiy.

Control

There are two main areas of control: test subject creation and execution.  To control a test subject we must be able to create it, get it ready for use in the test case, and execute it.  The difficulty of the execute part increases  when the test subject contains conditionals.  The questions below should be asked of any test subject when trying to determine its testability.

What makes a test subject easy/hard to create?

  • Is the constructor visabiltiy public?
  • If not is there a member in the test subject that is a substitute for the constructor?
  • Is there a default constructor?
  • If not is there a constructor that accepts few parameters?
  • Is the constructor loosely coupled to other types?
  • Is the constructor’s behaviour independent of other types?

What makes a test subject easy/hard to execute?

  • After construction is it ready to execute?
  • Are there no parameters?
  • Is the test subject loosely coupled to other types?
  • Is the test subject’s behaviour independent of other types?

An answer of no to any of those questions indicates a more difficult test subject to control.

Sense

There are two main areas of sensation as well: interaction with other types and value assignment (returning a value is included in value assignment).  For both types of sensation we must have a reference to the object the test subject is using.  If we do then it is very easy to sense if values were assigned, interaction on the other hand can get difficult.  Lets call the objects that the objects that the test subject interacts with actors, like the supporting cast in a play.  So if an actor is easy to create, setup, and it allows us to easily sense that the interaction between it and the test subject occurred correctly then it is easy to use in the test.  This is often not the case.  Often actors are difficult to create, setup, and or they hide what interaction did occur between it and the test subject.  This difficulty can be over come easily with test doubles, again with the acting analogy, think of a stand in or a stunt double.  The use of test doubles requires the test subject to know of actors by an abstraction; a base class or an interface.  The questions below should be asked of any test subject when trying to determine its testability.  Keep in mind that part of the test has already been written.

What makes a value assignment easy/hard to sense?

  • Do we already have a reference to the object the assignment was made to?
  • If not can we get a reference to the assignment object from an object we already have a reference to?
  • Can there be multiple instances of the assignment object? (if it is a singleton this complicates things)

What makes an interaction easy/hard to sense?

  • Is the test subject introverted (not interacting with other types)?
  • If not is there just one actor?
  • Do we already have a reference to each actor?
  • If not can we get a reference to the actor from an object that we already have a reference to?
  • Is each actor easy to control and does it expose evidence of interaction?
  • If not does the test subject know of the actor by an abstraction?

Again an answer of no to any of those questions indicates a more difficult test subject to sense.

Application

Lets play with this a little and say that an answer of no to a question earns a point.  So the ideal score is 0.  That means that the ideal test subject has these characteristics:

  • The constructor is public.
  • The constructor accepts no parameters, a default constructor.
  • The constructor interacts with no other types, its behaviour is independent.
  • The test subject is ready to execute after construction.
  • The test subject accepts no parameters.
  • The test subject interacts with no other types, its behaviour is independent.
  • The test subject returns a value and makes no other assignments.
  • The test subject is introverted, it interacts with no other types.
public class Ideal
{
    public Ideal(){}
 
    public String Method()
    {
        return “Hello World!”;
    }
}
 
[TestFixture]
public class TestsIdeal
{
    [Test]
    public void TestsMethod()
    {
        Ideal TestSubject = new Ideal();
        String ReturnValue;
        ReturnValue = TestSubject.Method();
        Assert.AreEqual("Hello World!", ReturnValue);
    }
}

 

So lets apply this to Jeremy’s post on State vs. Interaction Testing:

public class InvoiceProcessor
{
    public void ProcessInvoices(Invoice[] invoices)
    {
        InvoiceErrorReport report = new InvoiceErrorReport();
 
        foreach (Invoice invoice in invoices)
        {
            // Execute the validation business logic
            InvoiceError[] invoiceErrors = this.validateQuantities(invoice);
            report.StoreErrors(invoice, invoiceErrors);
        }
 
        // determine if the critical error threshold has been exceeded
        if (this.hasTooManyCriticalErrors())
        {
            MailMessage message = this.createErrorSummaryMessage(report);
            // Call to the local (or default) SMTP service to send the email
            SmtpMail.Send(message);
        }
           // determine if the warning threshold for the error count has been reached
        else if (this.hasTooManyErrors())
        {
            MailMessage message = this.createDetailsMessage(report);
            SmtpMail.Send(message);
        }
        else
        {
            // If the invoices are okay, send the invoices on to the next process via MSMQ
            MessageQueue queue = new MessageQueue(this.getMessageQueuePath());
            queue.Send(invoices);
        }
    }
}

 

The constructor gives us a score of 0 so we can move on to controlling the execution.  The test subject is not ready to execute after construction.  The MSMQ needs to be created and or purged.  The email server needs to be checked to see if it is ready for the test as well.  So there is 1 point.  There is one parameter so there is an other point: total 2.  The test subject is tightly coupled to several objects: total 3. Its behaviour is independent of other types.  It does not perform any value assignments.  It does interact with several other types: total 5 (1 for interaction and 1 for several).  We do not already have a reference to any of the actors nor is one exposed to us: total 7.  The SmtpMail type does not show evidence of interaction nor does the test subject know of it by abstraction: total 9.  The MessageQueue type does offer state based evidence of interaction (as long as there is no contention/competition for the message).  So we end up with a total of 9.  Jeremy goes on to show an improved design for testability.  Lets see the score produced, I hope it goes to show that these are the right questions to be asking.

public class InvoiceProcessor
{
    // “Dependency Inversion Principle” — All dependencies are now to an abstracted interface
    private readonly IEmailGateway _emailGateway;
    private readonly IMessagingGateway _messagingGateway;
    private readonly IUserInformationStore _userStore;
 
    // Use “Constructor Injection” to push dependencies into InvoiceProcessor
    public InvoiceProcessor(
        IEmailGateway emailGateway,
        IMessagingGateway messagingGateway,
        IUserInformationStore userStore)
    {
        _emailGateway = emailGateway;
        _messagingGateway = messagingGateway;
        _userStore = userStore;
    }
 
    public void ProcessInvoices(Invoice[] invoices)
    {
        InvoiceErrorReport report = new InvoiceErrorReport();
        foreach (Invoice invoice in invoices)
        {
            // Execute the validation business logic
            InvoiceError[] invoiceErrors = this.validateQuantities(invoice);
            report.StoreErrors(invoice, invoiceErrors);
        }
        // determine if the critical error threshold has been exceeded
        if (this.hasTooManyCriticalErrors())
        {
            MailMessage message = this.createErrorSummaryMessage(report);
            _emailGateway.SendMail(message);
        }
           // determine if the warning threshold for the error count has been reached
        else if (this.hasTooManyErrors())
        {
            MailMessage message = this.createDetailsMessage(report);
            _emailGateway.SendMail(message);
        }
        else
        {
            // no longer responsible for knowing where the MSMQ path is.  Or even if this
            // is an MSMQ
            _messagingGateway.SendInvoices(invoices);
        }
    }
}

 

It now has a constructor with parameters so we start of with a score of 2.  The test subject can be ready to execute immediately after construction if test doubles are used so we don’t get dinged for that any more.  The test subject still accepts one parameter: total 3.  It has improved in that it is loosely coupled to other types.  It does interact with other types, 1 point, and there is more than one: total 5.  We now have references to the types being interacted with, we had to pass them to the constructor.  The SmtpMail type still hides interactions for a point but the test subject now knows of it by an abstraction: total 6.  So the grand total after refactoring is a 6.

Tuning

I don’t mean the points part as stated here as a metric that should be used on any project.  It was just a means to illustrate, though I do think that with some tuning to the questions and the assignment of points a metric could be produced.  The answers to groups of the defined questions can even indicate particular design sicknesses and possible refactorings.



kick it on DotNetKicks.com