February, 2009 Archives

27
Feb

Conditional compilation

by Mikael Lundin in Programming

This is a feature that has been available to programmers since the dawn of compilers. It means that you may control what code is going to be included in the compilation on compile time. Let me give you an example:

#if Debug
    Console.WriteLine("Hello");
#else
    Console.WriteLine("World");
#endif

In the example above we control the output of WriteLine in compile time by defining what target to compile as. If we compile as Debug we will get “Hello”, else we will get “World”.

This seems harmless but is really a recipe for disaster when working in an enterprise environment. Given a compiled library, how do you know what target it was compiled as? What if you put the wrong target assemblies in the wrong environment?

How to use conditional compilation

Be very careful not to make your conditionals environment specific. If you need to execute different code paths depending on environment, use configuration to control this instead. You can always make sure that the configuration is correct when you try to debug a failing production environment.

You may however use conditional compilation when you want to take actions to enhance the environment that you’re working in. Here’s an example from Mint.

bool debug = false;

#if Debug // Enable stylesheet debug in development
debug = true;
#endif

XslCompiledTransform transformer = new XslCompiledTransform(debug);

Here I used conditional compilation to make sure that XSLT stylesheet debug is turned on while working in development environment, but turned off when deployed.

If this library with target Debug would find its way out to production, it wouldn’t be worse than a minor performance loss on XSLT transformations. In this scenario conditional compilation is neat, but beware of making your targets environment specific.

24
Feb

My rules of unit testing

by Mikael Lundin in Programming

In able to ensure the quality of my unit tests, I enforce a couple of rules that each and every test should conform to. Here are some of my rules, and why they’re so important.

Never call an external resource explicitly or in-explicitly through your unit test.

This means that you should not read from disk, make a web service call or read from a database in your unit test. This also means that your SUT (system under test) should not do so either. If you do want to test the integration between system parts you may use another kind of testing called integration testing.

The main reason is that you can’t depend on external resources. They may fail and you may not know why. Making your unit tests suite depending on a database or service uptime will make them useless half the time. (or when you checkout the code in some unknown environment)

Stay within the class

The smaller parts you intend to test, the easier it will be. Try to avoid your SUT to create instances of other classes that you do not intend to test. Every extra functionality may cause side effects you’re not prepared to meet. So, stay within the method, or at least within the class of your SUT.

Refactor your SUT

You can’t test that SUT as it is. You have to let the tests drive your design. If you find troubles testing a piece of code, it is most probably not you that fails on testing, but rather the SUT fail beeing testable. Change it so it is easier to test, and you will improve its design along the way.

Don’t mock unless you have to!

When I discovered the mocking tool I got all up over my ears. Now I’m not that excited anymore. Mocks are a good way to over specify your tests, because in the mock you record what should happen and in what order. Overspecification is one of the most dangerous anti-patterns for your tests.

Watch out for overspecification

People just stare at me blankly when I tell them to keep low coupling between the test and the SUT. Not surprisingly since it is plainly impossible. You have to call the SUT if you’re supposed to test it. But, you must watch out so that your tests don’t specify exactly how the SUT will work. If you do, you will find that your tests will break when you don’t intend them to. Every time you need to change a small piece of logic a test will break and leave you with twice the burdon to fix that bug. Don’t overspecify your tests! This is the hardest rule to follow.

Assert once and only once

A test should not assert more than once. This is because a test only should have one purpose, one thing to test. If you assert twice, you will test two things and should split it up in two tests. The reason for this is that you don’t really know what assertion failed when the test failed. What condition is no longer valid?

The cyclomatic complexity of your test should be 1.

This means that you should use no IF, no WHILE, no FOREACH and no other language construct that will make your test choose between two paths of execution. You want to keep your tests as simple as possible. If you need any language constructs like those I described, you have a problem in your SUT and should solve it there.

Your test should be only 10 lines of code (not counting comments)

This is also a rule to make my tests as simple as possible. If it is not possible to reduce the test to 10 lines of code, do I have a problem in my SUT or do I need to split the test up in two? This is not an absolute rule, but a rule to make me think about how to structure the tests and the SUT. I often sit and count line numbers. If they are more than 10, I have a problem.

(and yes, you can do mocking in 10 lines .. actually you should!)

Avoid intense setup/teardowns

If you need to do a lot of setup and teardown in your test/testfixture, you may have a problem. Code in setup and teardown scenarios that fail may bring down a whole test suite. I don’t use setup or teardown at all if I can avoid it, and I always do test specific setup/teardown in each test.

I probably forgot a lot of rules that I follow, but I wanted to share some of them with you. There is one rule that rules them all. Keep it simple, follow that rule and it can’t go wrong. If it is not simple, you will run into trouble. Now go out and unit test the world!

22
Feb

Unit test XSL transformations

by Mikael Lundin in Programming

Mint will be a very XSL transformation heavy application. That is why I’ve been thinking alot about how to manage all the transformation code. Well let’s start off with unit testing.

Unit testing XSLT?

Unit testing the transformation gives you the same benefits as unit testing any other code.

  • Regression testing, it will help you validate that the old stuff is still working while you add new functionality
  • It will help you structure your XSLT and write beautiful testable code
  • It will give you confidence about the stability of your code

How to unit tests XSLT

There’s already a whole language that will let you make sure that XML is valid. Since the result of my transformations will be XHTML I can use XML Schema to validate that the XSL script gave expected result.xslt_unittest

  1. Make sure that you split up your XSLT in templates so they will be easy to test.
  2. Write one or more XML snippets for each of these templates.
  3. Write XSD that defines what you expect after the snippet has been transformed
  4. Write a unit test that will be the engine of transformation of the snippet, to validation of the result. In Mint I use the NUnit extensions RowTest, and define the XML snippet filename and XSD Schema filename as input parameters. The files I store as embedded resources in the unit test library.

From now on you have your XSL transformations properly unit tested.

20
Feb

The value of attributes

by Mikael Lundin in Programming

I often rediscover the value of Attributes in C#. Very often it is hard to find a situation where you have need of attributes, you may be thinking that it is only for meta coding like unit testing or dynamic code intepretation/serializing, but you’re wrong. Attributes are useful every time you need to add meta data to a class, property or field. Let me give you the common example of adding label to an enum.

Problem: An enum defines genre in your music database. Now you want to display all available genres.

[Flags]
public enum Genre
{
    Other = 0,
    AlternativeRock = 1,
    HardRock = 2,
    WorldMusic = 4,
    Indie = 8,
    PostRock = 16
}

Start by defining the attribute Label.

public class LabelAttribute : Attribute
{
    public LabelAttribute(string text)
    {
        this.Text = text;
    }

    public string Text { get; set; }
}

Now you can add this to your genre values.

[Flags]
public enum Genre
{
    [Label("Other")]
    Other = 0,

    [Label("Alternative Rock")]
    AlternativeRock = 1,

    [Label("Hard rock")]
    HardRock = 2,

    [Label("World music")]
    WorldMusic = 4,

    [Label("Indie")]
    Indie = 8,

    [Label("Post-rock")]
    PostRock = 16
}

With the simple use of an extension method you may accomplish alot.

public static class LabelAttributeHelper
{
    /// <summary>
    /// Get label of an enum field
    /// </summary>
    public static string Label<T>(this T val)
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException("T must be an Enum");

        FieldInfo field = typeof(T).GetField(val.ToString());
        LabelAttribute[] attributes =
            (LabelAttribute[])field.GetCustomAttributes(typeof(LabelAttribute), false);

        if (attributes.Length == 0)
            throw new ArgumentOutOfRangeException("Enum value " + val.ToString() + " is missing Label attribute");

        return attributes.First().Text;
    }
}

Now you may easily type out all available genres with a simple procedure.

foreach (Genre genre in Enum.GetValues(typeof(Genre)))
    Console.WriteLine(genre.Label());

That’s all for today. Have a nice weekend!

19
Feb

Is it secret? Is it safe?

by Mikael Lundin in Technicalities

Gandalf, the one ringMany developers walk around every day with customers code in their laptops. The moment your code leaves the network (or building) where it is secure you put it at risk. A fun anecdote is that before release of the movie “Fellowship of the ring” one of the producers traveled with the most recent copy of the movie from New Zealand to London  for a last review before gold print. In London he nearly got mugged and had to run the last few blocks to Peter Jacksons home.

If he had gotten mugged, the movie had been released on the Internet before the premiere. That would have been a total disaster for both the production team and the economically for the company.

Every day developers are walking around with source in their pockets. What if they got mugged on the street? What if the source to that banking application found its way out on the Internet? Not only have your customer paid for that code, but they now also got a major security problem on their hands.

The solution is to encrypt all source code on your laptop. The best tool I’ve found for this is TrueCrypt. With this you can define a virtual encrypted hard drive or you may encrypt a whole partition.

Working from this encrypted drive is a bit slower than working from an unencrypted drive, but I’ve had no other problems with it, and I’ve been doing it for over a year. As a collegue of mine would say, this is still not secure. Given an amount of knowledge and an amount of time (and processing power), you may brute force this. But then again, if you have those kind of resources, you would more likely try to break into the repository and get the latest version.