Archive for October 2009

Team Foundation Server, msbuild unittest code coverage

If you are like me and wonder how much coverage your unittests have you can add coverage to your Team Foundation Server builds and see for yourself.

Note, I have only tried this using VS2008

First right click /Solution items in your solution explorer Add new item, choose Test run Configuration, let’s name it CodeCoverage.testrunconfig

Choose Code coverage on the left and choose the dll’s you want covered, save and check it in.

In your build.proj file find the first PropertyGroup, at the end of it add the line about the config file. You will need this in order for MsBuild to find the configuration. Then it will look similar to the xml below. Note the path, in my case I had to add \MYPROJECT to the mix as that’s where my source gets checked out on the build machine. You can see where that is on the server or check the build log and look at what directory the file is checked out to.

<PropertyGroup>
    …. snip
 
    <RunConfigFile>
        $(SolutionRoot)\MYPROJECT\CodeCoverage.testrunconfig
    </RunConfigFile>
  </PropertyGroup>

The coverage numbers will show up in the Unittest section of the build report. It is of course important to remember a well covered code does NOT mean that your unittests are any good. Most likely they are but the coverage number just means how much of the code was touched during the unittest run.

C# Base32

I had the need to use Base32 at work some time ago to compress numbers. I had forgotten about it until today when I ran across some old code. As I was researching implementation for a developer on another system we interact with. The problem at the time was that we had numbers that are too big to fit in the field where we needed to write it. In order to do so we needed to compress it and we choose Base32 for the task.

Simply put, you take a number and you convert it to the 32 characters in the convert table, for example.

123456789 becomes VITXVD

Of course when you have the Base32 encoded number you can decode it back to the original number. If you couldn’t do that it wouldn’t be very useful.

VITXVD becomes 123456789

The RFC 4648 Base 32 alphabet
Value Symbol Value Symbol Value Symbol Value Symbol
0 A 9 J 18 S 27 3
1 B 10 K 19 T 28 4
2 C 11 L 20 U 29 5
3 D 12 M 21 V 30 6
4 E 13 N 22 W 31 7
5 F 14 O 23 X
6 G 15 P 24 Y
7 H 16 Q 25 Z
8 I 17 R 26 2



Note that one and zero are not used so there is no confusion between them O and I. When shuffling data between different systems, legacy etc they might not be interpreted correctly. You can create the Base32 encoding in different ways. Therefor if your interacting with another system exchanging data that system needs to use the same encoding / decoding as your system.

Below is a C# sample Base32 code.

class CxBase32
    {
        //
        private const string BASE_32_ALPHABET = “ABCDEFGHIJKLMNOPQRSTUVWXYZ234567”;
        private static int BASE_LENGTH = BASE_32_ALPHABET.Length;
 
        // Encode number to base 32 string
        public static string toBase32( int piNumToCode )
        {
            StringBuilder sRet = new StringBuilder();
 
            // loop until nothing left
            do
            {
                // Set the encoded character using mod
                sRet.Append(BASE_32_ALPHABET[piNumToCode % BASE_LENGTH]);
                // Adjust the reminder
                piNumToCode = piNumToCode / BASE_LENGTH;
            }
            while (piNumToCode != 0);
 
            return sRet.ToString();
        }
 
 
        // Decode base 32 string to a number
        public static int fromBase32(string psCodedString)
        {
            int iRet = 0;
 
            // Decode the alphabet
            for (int i = psCodedString.Length1; i > –1; i–)
                { iRet = (iRet * BASE_LENGTH) + BASE_32_ALPHABET.IndexOf(psCodedString[i]); }
 
            return iRet;
        }
 
    }  // EOC
 

And unittests

[Test]
        // Make sure encoded number can be decoded correctly
        public void randomBase32Test()
        {
            // Try some random number
            string encoded = CxBase32.toBase32(123456789);
            Assert.AreEqual(“VITXVD”, encoded);
            int decode = CxBase32.fromBase32( encoded );
            Assert.AreEqual(123456789, decode);
           
            // Another number just for fun
            encoded = CxBase32.toBase32(987654321);
            Assert.AreEqual(“RF24N5”, encoded);
            decode = CxBase32.fromBase32(encoded);
            Assert.AreEqual(987654321, decode);
        }
       
        [Test]
        // Make sure zero will return a value
        public void zeroBase32Test()
        {
            // Zero test, should return a value as well
            string encoded = CxBase32.toBase32(0);
            Assert.AreEqual(“A”, encoded);
            int decode = CxBase32.fromBase32(encoded);
            Assert.AreEqual(0, decode);
        }