Ruthlessly Helpful

Stephen Ritchie's offerings of ruthlessly helpful .NET practices.

Category Archives: How To

Build Numbering and Versioning

Build numbering is a topic filled with “political” and “cultural” significance. I mean that within organizations and among developers, we have heated debates over the numbering of software versions. Is this software 2.3 or 3.0? Or should it be 2.3.5.7919, 2.3.5.rc-1, or 2.3.5.beta?

Phil Haack recently offered some important information on Semantic Versioning (SemVer) specification and NuGet build numbering. Since the SemVer convention is a rational and meaningful way to version public APIs, it’s a good one to follow. Here are Phil’s posts:

The basics of SemVer: the version number has three parts, Major.Minor.Patch, which correspond to:
Major: Backwards incompatible changes
Minor: New features that are backwards compatible
Patch: Backwards compatible bug fixes only.

Everything after these three numbers is for a development organization to use, as it sees fit. Personally, I like ever-increasing, always-unique-for-a-major.minor-version integer numbers. Whether these are build numbers or revision numbers they can be managed by the build script or the continuous integration server.

However, build numbering and versioning has political and cultural significance and implications. Sadly, developers cannot always follow rational and meaningful numbering schemes.

Marketing

The Marketing Department of a commercial software company often wants to control the first two digits of the build number. They love to promote things like the company’s software is no longer version 2.3; now it’s 3.0! This change in major version generates interest and drives upgrade sales. In some cases, the software is a major new release, with significant new features. In other cases, it is just a marketing gimmick; there are only bug fixes and cosmetic changes in the new version.

Internally, developers hate it when Marketing overstates the major and minor version numbers of software. They feel that a minor release does not warrant an increment of the major version number. They want to follow systems like SemVer.

My opinion: As long as the numbers don’t violate the conventions of SemVer, let the major and minor version numbers belong to Marketing.

Marketing controls the product name. I have seen some crazy product name changes come from Sales and Marketing. As long as it isn’t too absurd, I go along with it. Why shouldn’t that be the same way with the major and minor version numbers? If Marketing wants 2.2 to be followed by 3.0, that’s OK with me. Going from 2.2 to 2.5 could represent a more accurate description of the perceived improvement. Either way, I don’t see it as my call. What I don’t like is jumping from 2.2 to 5.0 or regressing from 2.2 to 1.7, that’s absurd. The major version number should never increment by more than one. The combined major and minor number should always represent a decimal number greater than the prior version. Similarly, going from 2.2 to 2.3 must only introduce backwards compatible new features and backwards compatible bug fixes.

Bottom line, let Marketing own the major and minor version numbers. Insist that they follow the basic rules. Give them the guidance that increasing the major version number means “breaking changes are introduced”, “significant new features are added” or “it’s a total rewrite.” Minor version numbers are incremented when minor enhancements are added and bug fixes are made. Marketing must not break the paradigm. They are adults. If they are using sound judgement, let them own the major and minor numbers.

NuGet and the Nu World Order

In the .NET world, NuGet is very significant. With version 1.6, NuGet follows the SemVer specification. My current thinking on version numbering is that you ought to follow the version numbering that NuGet follows. The NuGet documentation describes the SemVer spec and what NuGet expects of version numbering.

Continuous Integration Server

The CI server is a great way to control and increment the version number.

Cruise Control .NET (CCNet) has the Assembly Version Labeller and TeamCity has the AssemblyInfo Patcher.

Incorporate this version numbering into your build script. Chapter 9 of Pro .NET Best Practices covers this topic. The free code samples are available at the bottom of the Apress page for the book, here.

Here is a good way to version assemblies: http://code.google.com/p/svnrevisionlabeller/

Ben Hall describes how to increment the build numbers with MSBuild and TeamCity: http://blog.benhall.me.uk/2008/06/team-city-update-assemblyinfo-with.html

Wikipedia, as usual, has a comprehensive entry on the topic of software versioning: http://en.wikipedia.org/wiki/Software_versioning

Four Ways to Fake Time, Part 3

In Part 2 of this four part series you learned how to use a class property to change the code’s dependency on the system clock to make the code easier to test. Adding the Now property is effective, however, adding a new property to every class isn’t always the best solution.

I don’t remember exactly when I first encountered the IClock interface. I do remember having to deal with the testability challenges of the system clock about 5 years ago. I was developing a scheduling module and needed to write tests that verified the code’s correctness. I think I learned about the IClock interface when I researched the MbUnit testing framework. At some point I read about IDateTime in Ben Hall’s blog or this article in ASP Alliance. I also read about FreezeClock in Ben’s post on xUnit.net extensions. Over time I collected the ideas and background that underlie this and similar approaches.

Fake Time 3: Inject The IClock Interface

I usually create a straightforward IClock interface within some utility or common assembly of the system. It becomes a low-level primitive of the system. In this post, I simplify the IClock interface just to keep the focus on the primary concept. Below I provide links to more detailed and elaborate designs. Without further ado, here is the basic IClock interface:

using System;

namespace Lender.Slos.Utilities.Clock
{
    public interface IClock
    {
        DateTime Now { get; }
    }
}

By using the IClock interface, the code in our example class is modified so that it has a dependency on the system clock through a new constructor parameter. Here is the rewritten code-under-test:

using System;
using Lender.Slos.Utilities.Clock;
using Lender.Slos.Utilities.Configuration;

namespace Lender.Slos.Financial
{
    public class ModificationWindow
    {
        private readonly IClock _clock;
        private readonly IModificationWindowSettings _settings;

        public ModificationWindow(
            IClock clock,
            IModificationWindowSettings settings)
        {
            _clock = clock;
            _settings = settings;
        }

        public bool Allowed()
        {
            var now = _clock.Now;

            // Start date's month & day come from settings
            var startDate = new DateTime(
                now.Year,
                _settings.StartMonth,
                _settings.StartDay);

            // End date is 1 month after the start date
            var endDate = startDate.AddMonths(1);

            if (now >= startDate &&
                now < endDate)
            {
                return true;
            }

            return false;
        }
    }
}

Under non-test circumstances, the SystemClock class, which implements the IClock interface, is passed through the constructor. A very simple SystemClock class looks like this:

using System;

namespace Lender.Slos.Utilities.Clock
{
    public class SystemClock : IClock
    {
        public DateTime Now
        {
            get { return DateTime.Now; }
        }
    }
}

For those of you who are using an IoC container, it should be clear how the appropriate implementation is injected into the constructor when this class is instantiated. I recommend you use constructor DI when using the IClock interface approach. For those following a Factory pattern, the factory class ought to supply a SystemClock instance when the factory method is called. If you’re not loosely coupling your dependencies (you ought to be) then you need to add another constructor that instantiates a new SystemClock, kind of like this:

public ModificationWindow(IModificationWindowSettings settings)
    : this(new SystemClock(), settings)
{
}

In this post, we are most concerned about improving the testability of the code-under-test. The revised test method sets up the IClock.Now property so as to return currentTime as its value. This, in effect, fakes the Allowed method, and establishes a known value for the system clock. Here is the revised test code:

[TestCase(1)]
[TestCase(5)]
[TestCase(12)]
public void Allowed_WhenCurrentDateIsInsideModificationWindow_ExpectTrue(
    int startMonth)
{
    // Arrange
    var settings = new Mock<IModificationWindowSettings>();
    settings
        .SetupGet(e => e.StartMonth)
        .Returns(startMonth);
    settings
        .SetupGet(e => e.StartDay)
        .Returns(1);

    var currentTime = new DateTime(
        DateTime.Now.Year,
        startMonth,
        13);

    var clock = new Mock<IClock>();
    clock
        .SetupGet(e => e.Now)
        .Returns(currentTime); // Setup getter to return the test's clock

    var classUnderTest = 
        new ModificationWindow(
            clock.Object,
            settings.Object);

    // Act
    var result = classUnderTest.Allowed();

    // Assert
    Assert.AreEqual(true, result);
}

If you’re looking for more depth and detail, take a look at this very good post on the IClock interface by Al Gonzalez: http://algonzalez.tumblr.com/post/679028234/iclock-a-test-friendly-alternative-to-datetime

The Gallio/MbUnit testing framework has its own IClock interface. I don’t like production deployments containing testing framework assemblies; however, the Gallio approach offers a few ideas to enhance the IClock interface.

Pros:

  • Works well with an IoC Container/Dependency Injection approach
  • Can work with .NET Framework 2.0 and later
  • No impact on class-users and method-callers
  • A system-wide approach
  • Testability is greatly improved

Cons:

  • System-wide change, some risk
  • Can be disruptive when applied to legacy or Brownfield applications

I often use this approach when working in Greenfield application development or when major refactoring is warranted.

In the next part of this Fake Time series we’ll look at a mock isolation framework approach.

Four Ways to Fake Time, Part 2

In Part 1 of this four part series you learned how a code’s implicit dependency on the system clock can make the software difficult to test. The first post presented a very simple solution, pass in the clock as a method parameter. It is effective, however, adding a new parameter to every method of a class isn’t always the best solution.

Fake Time 2: Brute Force Property Injection

Here is a second way to fake time. It is brute force in the sense that it is rudimentary. Using full-blown dependency injection with an IoC container is left as an exercise for the reader. The goal of this post is to illustrate the principle and provide you with a technique you can use today.

Perhaps an example would be helpful …

using System;
using Lender.Slos.Utilities.Configuration;

namespace Lender.Slos.Financial
{
    public class ModificationWindow
    {
        private readonly IModificationWindowSettings _settings;

        public ModificationWindow(
            IModificationWindowSettings settings)
        {
            _settings = settings;
        }

        // This property is for testing use only
        private DateTime? _now;
        public DateTime Now
        {
            get { return _now ?? DateTime.Now; }
            internal set { _now = value; }
        }

        public bool Allowed()
        {
            var now = this.Now;

            // Start date's month & day come from settings
            var startDate = new DateTime(
                now.Year,
                _settings.StartMonth,
                _settings.StartDay);

            // End date is 1 month after the start date
            var endDate = startDate.AddMonths(1);

            if (now >= startDate &&
                now < endDate)
            {
                return true;
            }

            return false;
        }
    }
}

In this example code, the Allowed method changed very little from how it was written at the end of the first post. The primary difference is that there isn’t any clock optional argument. The value of the now variable comes from the new class property named Now.

Let’s take a closer look at the Now property. First, it has a backing variable named _now, which is declared as a nullable DateTime. Second, since _now defaults to null, this means that the Now property getter will return System.DateTime.Now if the property is never set. In other words, if the Now property is never set then that property behaves like a call to System.DateTime.Now.

Note that the null coalescing operator (??) expression in the getter can be rewritten as follows:

get
{
    return _now == null ? DateTime.Now : _now.Value;
}

And so, if our test code sets the Now property to a specific DateTime value then that property returns that DateTime value, instead of System.DateTime.Now. This allows the test code to “freeze the clock” before calling the method-under-test.

The following is the revised test method. It sets the Now property to the currentTime value at the end of the arrangement section. This, in effect, fakes the Allowed method, and establishes a known value for the clock.

[TestCase(1)]
[TestCase(5)]
[TestCase(12)]
public void Allowed_WhenCurrentDateIsInsideModificationWindow_ExpectTrue(
    int startMonth)
{
    // Arrange
    var settings = new Mock<IModificationWindowSettings>();
    settings
        .SetupGet(e => e.StartMonth)
        .Returns(startMonth);
    settings
        .SetupGet(e => e.StartDay)
        .Returns(1);

    var currentTime = new DateTime(
        DateTime.Now.Year,
        startMonth,
        13);

    var classUnderTest = new ModificationWindow(settings.Object);

    classUnderTest.Now = currentTime; // Set the value of Now; freeze the clock

    // Act
    var result = classUnderTest.Allowed();

    // Assert
    Assert.AreEqual(true, result);
}

There is one more subtlety to mention. The test method cannot set the class-under-test’s Now property without being allowed access. This is accomplished by adding the following line to the end of the AssemblyInfo.cs file in the Lender.Slos.Financial project, which declares the class-under-test.

[assembly: InternalsVisibleTo("Tests.Unit.Lender.Slos.Financial")]

The use of InternalsVisibleTo establishes a friend assembly relationship.

Pros:

  1. A straightforward, KISS approach
  2. Can work with .NET Framework 2.0
  3. No impact on class-users and method-callers
  4. Isolated change, minimal risk
  5. Testability is greatly improved

Cons:

  1. Improves testability only one class at a time
  2. Adds a testing-use-only property to the class

I use this approach when working with legacy or Brownfield code. It is a minimally invasive technique.

In the next part of this Fake Time series we’ll look at the IClock interface and a constructor injection approach.

Four Ways to Fake Time

Are your unit tests failing because the code-under-test is coupled to the system clock? In other words, does the method you are testing use the System.DateTime.Now property, and that dependency is making it hard to properly unit test the code?

Calendar

This series of posts presents four ways to fake time as a means of improving testability. Specifically, we’ll look at these four techniques:

  1. The Optional ‘clock’ Parameter
  2. Brute Force Property Injection
  3. Inject The IClock Interface
  4. Mock Isolation Framework

Time Is Bumming Me Out

Time is so rigid. It keeps on ticking, ticking … into the future. The code becomes dependent on the system clock. That dependency makes it hard to properly test the code. Worse, the test code cannot find a lurking bug … until *boom* … the bug blows the system up.

Perhaps an example would be helpful …

public bool Allowed()
{
    // Start date's month & day come from settings
    var startDate = new DateTime(
        DateTime.Now.Year,
        _settings.StartMonth,
        _settings.StartDay);

    // End date is 1 month after the start date
    var endDate = new DateTime(
        DateTime.Now.Year,
        _settings.StartMonth + 1, // This is the lurking bug!
        _settings.StartMonth);

    if (DateTime.Now >= startDate &&
        DateTime.Now < endDate)
    {
        return true;
    }

    return false;
}

Notice the lurking bug in this code? Well, if the start month is December then a defect emerges at runtime. The error message you would see looks something like this:

System.ArgumentOutOfRangeException : Year, Month, and Day parameters describe an un-representable DateTime.

This defect is not too hard to notice, if you envision the value in the _settings.StartMonth property is 12. However, the problem with lurking bugs, they go unnoticed until … bang! At some future date (all too often in production) the software hiccups.

In the following code sample, the defect will be found when the continuous integration server runs the tests in December. This is a fairly typical unit testing approach, intended to test the Allowed method.

[Test]
public void Allowed_WhenCurrentDateIsOutsideModificationWindow_ExpectFalse()
{
    // Arrange
    var startMonth = DateTime.Now.Month;

    var settings = new Mock<IModificationWindowSettings>();
    settings
        .SetupGet(e => e.StartMonth)
        .Returns(startMonth + 1);
    settings
        .SetupGet(e => e.StartDay)
        .Returns(1);

    var classUnderTest = new ModificationWindow(settings.Object);

    // Act
    var result = classUnderTest.Allowed();

    // Assert
    Assert.AreEqual(false, result);
}

You don’t want to go into work on 1-Dec and find that this test is suddenly failing. The test method fails in December because that’s when startMonth is 12 and the defect is revealed. You’ll have a sickening thought, “Wait a second … is it failing in production?”

The production code is not working as intended, and worse than that, the test code never found the issue before the defect went into production.

If you revise the test code to include a few test cases, like the ones shown below, then the boundary conditions are covered and the defect is found every time these test cases are run. However, this test method has another flaw. It cannot pass for all three cases because the code-under-test has a dependency on DateTime.Now.

[TestCase(1)]
[TestCase(5)]
[TestCase(12)]
public void Allowed_WhenCurrentDateIsOutsideModificationWindow_ExpectFalse(
    int startMonth)
{
    // Arrange
    var settings = new Mock<IModificationWindowSettings>();
    settings
        .SetupGet(e => e.StartMonth)
        .Returns(startMonth + 1);
    settings
        .SetupGet(e => e.StartDay)
        .Returns(1);

    var classUnderTest = new ModificationWindow(settings.Object);

    // Act
    var result = classUnderTest.Allowed();

    // Assert
    Assert.AreEqual(false, result);
}

Before we investigate any further, let’s go back and revise the code-under-test to fix the bug. Here is an improved implementation of the Allowed method.

public bool Allowed()
{
    // Start date's month & day come from settings
    var startDate = new DateTime(
        DateTime.Now.Year,
        _settings.StartMonth,
        _settings.StartDay);

    // End date is 1 month after the start date
    var endDate = startDate.AddMonths(1);

    if (DateTime.Now >= startDate &&
        DateTime.Now < endDate)
    {
        return true;
    }

    return false;
}

Imagine that today is Friday the 13th of January 2012. When we run the test cases the first case passes, but the other two fail. We want all three test cases to pass every time they are run.

Fake Time 1: The Optional ‘Clock’ Parameter

Let’s change the code-under-test so that time is provided as an optional parameter. This approach is made possible by .NET Framework 4.0, which allows C# developers to define optional parameters.

public bool Allowed(DateTime? clock)
{
    var now = clock ?? DateTime.Now; // If no clock is provided then use Now.

    // Start date's month & day come from settings
    var startDate = new DateTime(
        now.Year,
        _settings.StartMonth,
        _settings.StartDay);

    // End date is 1 month after the start date
    var endDate = startDate.AddMonths(1);

    if (now >= startDate &&
        now < endDate)
    {
        return true;
    }

    return false;
}

Now that the code-under-test accepts this ‘clock’ parameter, the test method is modified, as follows. All three test cases now pass.

[TestCase(1)]
[TestCase(5)]
[TestCase(12)]
public void Allowed_WhenCurrentDateIsInsideModificationWindow_ExpectTrue(
    int startMonth)
{
    // Arrange
    var settings = new Mock<IModificationWindowSettings>();
    settings
        .SetupGet(e => e.StartMonth)
        .Returns(startMonth);
    settings
        .SetupGet(e => e.StartDay)
        .Returns(1);

    var currentTime = new DateTime(
        DateTime.Now.Year,
        startMonth,
        13);

    var classUnderTest = new ModificationWindow(settings.Object);

    // Act
    var result = classUnderTest.Allowed(currentTime);

    // Assert
    Assert.AreEqual(true, result);
}

Pros:

  1. The simplest thing that could possibly work; a KISS approach
  2. Minimal impact to method callers
  3. Isolated changes, lower risk
  4. Testability is greatly improved

Cons:

  1. Only works with .NET Framework 4
  2. Method callers are able to pass improper dates and times, invalidating the method’s expected behavior
  3. Improves testability only one method at a time
  4. Adds testing-use-only parameters to method signatures

I recommend this approach when working with legacy or Brownfield code, which has been brought up to .NET 4, and a minimally invasive, very isolated technique is indicated.

In the next part of this Fake Time series we’ll look at a brute force, property injection approach.

Liberate FxCop 10.0

Update 2012-06-04: It still amazes me that not a thing has changed to make it any easier to download FxCopSetup.exe version 10 in the nearly two years since I first read this Channel 9 forum post: http://channel9.msdn.com/Forums/Coffeehouse/561743-How-I-downloaded-and-installed-FxCop As you read the Channel 9 forum entry you can sense the confusion and frustration. However, to this day the Microsoft Download Center still gives you the same old “readme.txt” file instead of the FxCopSetup.exe that you’re looking for.

Below I describe the only Microsoft “official way” (no, you’re not allowed to distribute it yourself) — that I know of — to pull out the FxCopSetup.exe so you can install it on a build server, distribute within your team, or to do some other reasonable thing. It is interesting to note the contrast: the latest StyleCop installer is one mouse click on this CodePlex page: http://stylecop.codeplex.com/

Update 2012-01-13: Alex Netkachov provides short-n-sweet instructions on how to install FxCop 10.0 on this blog post http://www.alexatnet.com/content/how-install-fxcop-10-0

Quick, flash mob! Let’s go liberate the FxCop 10.0 setup program from the Microsoft Windows SDK for Windows 7 and .NET Framework 4 version 7.1 setup.

Have you ever tried to download FxCop 10.0 setup program? Here are the steps to follow, but a few things won’t seem right:

1. [Don’t do this step!] Go to Microsoft’s Download Center page for FxCop 10.0 (download page) and perform the download. The file that is downloaded is actually a readme.txt file.

2. The FxCop 10.0 read-me file has two steps of instruction:

FxCop Installation Instructions
1. Download the Microsoft Windows SDK for Windows 7 and .NET Framework 4 version 7.1.
2. Run %ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\FXCop\FxCopSetup.exe to install FxCop.

3. On the actual FxCop 10.0 Download Center page, under the Instructions heading, there are slightly more elaborate instructions:

• Download the Microsoft Windows SDK for Windows 7 and .NET Framework 4 Version 7.1 [with a link to the download]
• Using elevated privileges execute FxCopSetup.exe from the %ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\FXCop folder

NOTE:

On the FxCop 10.0 Download Center page, under the Brief Description heading, shouldn’t the text simply describe the steps and provide the link to the Microsoft Windows SDK for Windows 7 and .NET Framework 4 version 7.1 download page? That would be more straightforward.

4. Use the Microsoft Windows SDK for Windows 7 and .NET Framework 4 version 7.1 link to jump over to the SDK download page.

5. [Don’t actually download this, either!] The estimated time to download on a T1 is 49 min. The download file is winsdk_web.exe is 498 KB, but under the Instruction heading the explanation is provided: The Windows SDK is available thru a web setup (this page) that enables you to selectively download and install individual SDK components or via an ISO image file so that you can burn your own DVD. Follow the link over to download the ISO image file.

6. Download the ISO image file on the ISO download page. This is a 570 MB download, which is about 49 min on a T1.

7. Unblock the file and use 7-Zip to extract the ISO files.

8. Navigate to the C:\Downloads\Microsoft\SDK\Setup\WinSDKNetFxTools folder.

9. Open the cab1.cab file within the WinSDKNetFxTools folder. Right-click and select Open in new window from the menu.

10. Switch over to the details file view, sort by name descending , and find the file that’s name starts with WinSDK_FxCopSetup.exe … ” plus some gobbledygook (mine was named “WinSDK_FxCopSetup.exe_all_enu_1B2F0812_3E8B_426F_95DE_4655AE4DA6C6”.)

11. Make a sensibly named folder for the FxCop setup file to go into, for example, create a folder called C:\Downloads\Microsoft\FxCop\Setup.

12. Right-click on the “WinSDK_FxCopSetup.exe + gobbledygook” file and select Copy. Copy the “WinSDK_FxCopSetup.exe + gobbledygook” file into C:\Downloads\Microsoft\FxCop\Setup folder.

13. Rename the file to “FxCopSetup.exe”. This is the FxCop setup file.

14. So the CM, Dev and QA teams or anyone on the project that needs FxCop doesn’t have to perform all of these steps copy the 14 MB FxCopSetup.exe file to a network share.

That’s it. Done.

Apparently, a decision was made to keep the FxCop setup off Microsoft’s Download Center. Now the FxCop 10 setup is deeply buried within the Microsoft Windows SDK for Windows 7 and .NET Framework 4 Version 7.1. Since the FxCop setup was easily available as a separate download it doesn’t make sense to bury it now.

Microsoft’s FxCop 10.0 Download Page really should offer a simple and straightforward way to download the FxCopSetup.exe file. This is way too complicated and takes a lot more time than is appropriate to the task.

P.S.: Much thanks to Matthew1471’s ASP BlogX post that supplied the Rosetta stone needed to get this working.