Thursday, December 17, 2009

Overlapping dates

Had an interesting problem a few nights ago which at first seemed like a really easy thing, but turned out to be a right pain in the face.  I figured I’d do a blog on it as it might help someone else later on.

A Simple Problem .. not !!

What I wanted to figure out was if two date ranges overlapped.  the logic of this was a lot harder to get my head around than I first expected.  As I was dealing with a range rather than static dates any of the existing DateTime functions were useless, also working with TimeSpans I find difficult.  The solution was to create a good Test case and keep playing around with the logic.

[Test(Description="Test over lapping dates")]
[TestCase("2009-12-17 13:00:00", "2009-12-17 17:00:00", "2009-12-17 13:00:00", "2009-12-17 13:00:00", true)]
[TestCase("2009-12-17 13:00:00", "2009-12-17 13:30:00", "2009-12-17 14:00:00", "2009-12-17 14:30:00", false)]
public void CompareDatesTest(string firstStartDate, string firstEndDate, string secondStartDate, string secondEndDate, bool expectedOverlap)
{
     DateTime first_start_date = DateTime.Parse(firstStartDate);
     DateTime first_end_date = DateTime.Parse(firstEndDate);
     DateTime second_start_date = DateTime.Parse(secondStartDate);
     DateTime second_end_date = DateTime.Parse(secondEndDate);
     //Compare
     Assert.IsTrue(DatesOverlap(first_start_date, first_end_date, second_start_date, second_end_date) == expectedOverlap, "booking overlap validation did not work");
}

the test case above will run two dates through my logic and return True if the first and second date rages overlap, False if they don’t.

My magic function

To work out the problem I had to convert the dates into Ticks.  This converts the date in the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001.  Using that conversion I can easily use the numerical Great-than Boolean functions…. so after much playing around with IF statements I came up with:

private bool DatesOverlap(DateTime firstStart, DateTime firstEnd, DateTime secondStart, DateTime secondEnd)
{
     return (firstEnd.Ticks >= secondStart.Ticks) && (secondEnd.Ticks >= firstStart.Ticks);
}

After doing all this I then did a quick Google to find someone had come up with the same solution.  D’oh!.

Friday, December 11, 2009

Reflecting Classes and content

Yesterday someone asked for a way to print out all the contents of a class including the values that were current assigned.  This initially seemed like an easy thing to do, but turned out to be a little more complicated that expected.

The Easy Way

First thing we need to understand about .NET classes is that they are all inherited from a base type called Object.  This base object has a handy little method called ToString(), which will return you a string representation of that object.  You would have used this dozens of times in your code.

int X = 32;
Console.WriteLine("The value of X is:” + X.ToString());

image

This returns “The value of X is:32” which is fine for simple objects like int, float, DateTime but what about our custom classes?.  If you coded up something like the following:

public class SomeObject
{
    public string Firstname { get; set; }
    public string Surname { get; set; }
}

Now you’re test code would look like this:

SomeObject someObject = new SomeObject();
someObject.Firstname = "Tiberius";
someObject.Surname = "Percinus";
Console.WriteLine("The value of someObjectis: " + someObject.ToString());

image

This returns “The value of someObject is: UnitTests.ReflectionExample.SomeObject” which is not really helpful at all.  The normal way around this is to create an override on the ToString() method which returns a more meaningful result.

    public class SomeObject
    {
        public string Firstname { get; set; }
        public string Surname { get; set; }

        /// <summary>
        /// Local implementation of ToString based on class members
        /// </summary>
        public override String ToString()
        {
            StringBuilder sbuffer = new StringBuilder();
            sbuffer.Append("{");
            sbuffer.AppendFormat("Firstname = {0}, ", this.Firstname);
            sbuffer.AppendFormat("Surname = {0}, ", this.Surname);
            sbuffer.Append(" }");
            return sbuffer.ToString();
        }
    }

With this we create a large string with all of the local values returned in a meaningful way.

image 

This returns: “The value of someObject is: {Firstname = Tiberius, Surname = Percinus,  }”.

The Fancy Way

“OK”, I was told, “But this object has only two data items what happens if I’ve got 180?”.  Which is a very valid question.  The best answer to this is to use a technique called “Reflection” which allows you to crack open a class to access its values.

    using System.Reflection;

    public class SomeObject
    {
        public string Firstname { get; set; }
        public string Surname { get; set; }
         //  ……  assume another 180 properties are here ……  //
        public string LastProperty { get; set; }

        /// <summary>
        /// Local implementation of ToString based on reflection
        /// </summary>
        public override String ToString()
        {
            StringBuilder sbuffer = new StringBuilder();
            sbuffer.Append("{");
            PropertyInfo[] properties = this.GetType().GetProperties();
            foreach (PropertyInfo prop in properties)
            {
                sbuffer.AppendFormat("{0} = {1}, ", prop.Name, prop.GetValue(this, null));
            }
            sbuffer.Append(" }");
            return sbuffer.ToString();
        }
    }

Using the foreach loop and the GetType().GetProperties() methods we get an array of all properties in the class.  Then we just have string builder join them all together.

image

This will now return: “The value of someObject is: {Firstname = Tiberius, Surname = Percinus, … and on for all the properties … , LastProperty = ,  }”.

So why not do this all the time? Well the simple reason is that reflection adds a little more load on the processor, so for the majority of cases it’s best to stick to “the easy way”, unless you have a very, very large set of properties.

Tuesday, December 8, 2009

Conditional Pre-Complication is good for what ails you.

Recently found a comments in the code base that stated "Remove on Live!" in the description.  It was perfectly valid code, but unfortunately but there was no way any developer (other than the person who wrote it in the first place) will remove the code before compiling.  The good news is that there is a solution to this problem and that’s "Conditional Pre-Compilation Symbols".  That all sounds very complicated but its really simple.  It means you can mark a section of code, so that it is placed within a specific assembly.

Simple Conditional Pre-Complication

Here is an example of a function that will appear in all environments and assemblies.

//***********************************
// Test code; remove when running on live.
//***********************************
  if (X==Y || Z==A)

{  
      int AnotherX = Convert.ToInt32(X)|
      _log.DebugFormat("AnoterX has been set to {0}", X);
  }

Pleacing this within a Conditional Pre-Compilation Symbols would look like this:

#if(DEBUG)

   //***********************************
   // Test code; remove when running on live.
   //***********************************
   if (X==Y || Z==A
   {  

      int AnotherX = Convert.ToInt32(X)|
      _log.DebugFormat("AnoterX has been set to {0}", X);
    }

#endif

This means that the code still works fine on you're local PC and Miranda, but now that we're using CC.NET to do a "Release" build, this code will not be included in the assembly.

Doing something more funky

You're not limited to just removing code, you can also directly change the code as shown below:

#if(DEBUG)

      _log.DebugFormat("This is Debug Code");

#else

      _log.DebugFormat("This is Release Code");

#endif

You are also not limited to only using the pre-configured "DEBUG" or "RELEASE" variables, you can also set your own.  To do this, open the property page for your project and select the Build tab.  Here you can see a field called "Conditional compilation symbols".  Here you can enter a value like "Design", but you should also note the Configuration currently selected as this is important. 

image

Now in your code you can do this….

  #if(Design)

      _log.DebugFormat("This is only run when Design is entered in the properties");

  #endif

You can of course add as many build configurations as you wish, e.g. “Debug”, “Test”, “Stage”, “Live” etc. and CC.NET will happy ensure that each is built in turn correctly.

Wednesday, November 25, 2009

Generics your easy road to the simple life

There have been some comments recently asking what was the best way to use Generics in C#, so here’s a short blog which sheds some light.  Generics were probably the most powerful feature to go into .Net and they allowed developers to define structures, without committing to actual data types.  That may sound very complicated but its really not that hard to wrap your head around.

Simple Generic Lists

One of the simplest examples is taken directly from an existing Framework.  Within this we have lots of Collections classes for example CompanyCollection, ContactCollection, etc. and these are explicitly created with lots of code for getting a group, array of Company or Contact items from the CompanySearch class. 

It's usually seen in this type of context:

// Get a collection of companies

CompanyCollection compCollection = CompanySearch.Browes();

string companyName = compCollection[0].CompName;  // display the first company name

Generics give you the same thing out of the box using the List<> function.

// Get a collection of companies using Generics

List<Company> compCollection = CompanySearch.Browes();

string companyName = compCollection[0].CompName;

So what's the advantage?  Well for one we don't need the CompanyCollection.cs class file which will save a developer having to write it (cut/paste or use replicator and perhaps introduce bugs).  Secondly it's been developed using core functions so it's faster than anything you could write yourself.  Also it's guaranteed to give us a stable upgrade path as .Net progresses.

The Syntax

Taking this example a little further, I hear “What’s all this <> crap in the code?”.  Well simply, this is the class you are passing into a “generic” (i.e. self defined) method.  An easy way to describe this is to think of it as a cut/paste job for the class.  Below is an extract of the CompanyCollection class with a Browse method.

using System;
using System.Collections;

namespace BusinessObjects.Companies
{
    public class CompanyCollection : CollectionBase
    {
        public CompanyColelction Browse()
        {
              CompanyCollection results = new CompanyCollection();
              … some code to find a bunch of records and put them in results …
              return results;
        }
}

If you wanted the same thing for Contacts you would probably cut/paste the code into a new file and replace every occurrence of “"CompanyCollection” with “ContactCollection”.  With Generics you would say something like this.

using System;
using System.Collections;

namespace BusinessObjects.Companies
{
    public class GenericList<T>
    {
        public GenericList<T> Browse()
        {
              GenericList<T> results = new GenericList<T>();
              … some code to find a bunch of records and put them in results …
              return results;
        }
}

Here at compile time the .Net Framework will replace the “T” above with the object value you are passing to the method.

GenericList<Company> myCompanyCollection = new GenericList<Company>();  // replace “T”
myCompanyCollection.Browse();

and

GenericList<Contact> myContactCollection = new GenericList<Contact>(); // replace “T”
myContactCollection.Browse();

Hence in the compiled DLL, you do actually get two classes “generic classes” but you only have to write (or edit, debug, etc.) one!

Thursday, November 19, 2009

Some coding tips and advice

I've been doing some refactoring code recently and want to share some tips and tricks that could help developers in future efforts.  These are just suggestions so feel free to use or ignore any of them, but keep in mind that they would make things a little easier for everyone in the long run.

Temp Files and Paths

I've seen in a few places that developers have been placing files into the C:\temp directory.  Nothing wrong with this; however did you know that .NET makes it a lot easier now?

Before:    string fullFileName = @"c:\temp\" + someFileName;
The main problem here this is that it assumes that the "c:\temp\" directory exists and if you want to change it we have to recompile the source code.

After:      string fullFileName = String.Format("{0}{1}", Path.GetTempPath(),
                                                                                 Path.GetTempFileName());
The "Path" class in .NET will gives you lots of extra options for dealing with folders and files.  The "GetTempPath" method will return the value set in the %Temp% environment variable which is default in Windows.  "GetTempFileName" will give you a random filename which can be very handy if you are creating temp files.  Another handy methods are "GetFileNameWithoutExtension" which means you can add any extension you want to a file.

Getting rid of old code

You all know how much I *hate* to leave old code hanging around, but leaving an entire classes really gets me going!  The current Framework is chock full of classes that are old, duplicated or simply in need of a serious rewrite, but we can't delete them as there is the ever present "Possibility" of breaking the old ASP code.  To address this we can use the "Obsolete" attribute to show a class should no longer be used.

    [Obsolete("This class is a deprecated! use Company from DataAccessObjects Namespace.")]
    public class Company
    {     ......     }

We can also say something like this  [Obsolete("This class is a deprecated and will throw a compile error!", true)].  This is Visual Studio will generate a compile error, but it's probably not something you'd want to do unless you really wanted to spend a long time testing.

Never..Never.. Never.. Swallow Errors!

I've seen this type of code all over every project and it's really bad practice.

     try { someCode;
           someMoreCode; }
     catch (Exception e) { }
AAGHHH!!! having a catch with nothing in it is like driving drunk with your eyes closed and having no insurance, it's just saying "If I crash, just keep going and leave all that damage for someone else".

     try { someCode;
           someMoreCode; }
     catch (Exception e) { throw new e;}
This is a little (but not much) better than the last example; least this this we acknowledge that a problem took place.  The problem with this approach is that as we're throwing a "new e" so we actually loose the strack trace and if the error is deep in the bowls of the code you'll have a hard job finding the cause.

     try { someCode;
           someMoreCode; }
     catch (Exception e) { throw;}

This will give you both the error and the stack trace, but really at this point its probably easier to just say:

         someCode;
         someMoreCode;

So what's the moral of our story?  NEVER have a try-catch block unless you actually need to do something with it, log the error, throw a different error, it’s up to you but please do something in the catch block.

Creating Projects in the right folder

A very minor thing on the list is to keep an eye on the directory when you're adding a new project to an existing solution.  By default if I was to add a new project to a solution it will go under the root folder.  There however a text box on the New Project dialogue which gives you the option to add a subdirectory name.

Friday, November 13, 2009

PSTools .. it’s great to find a good tool for once!

I was looking for a way to run scripts on a remote server and found this great set of tools that are freely available from Microsoft.

PSTools; this is basically a set of tools that let you manage a remote server as if it was a local one.  this contains a number of different commands which are all listed on the website.  I’m going to integrate the PSExec command into the project Build Scripts.

Monday, November 9, 2009

Unit Testing types for developers

Well you all know I'm a big fan of Unit Testing but did you know all the different types of tests you can run?  In this Blog I'll go over some of the examples:

A simple class to test

First we need a simple class to test so I'll use a very, very simple addition and division example called SimpleClass.  It contains two methods Add and Division both of which take two integers and return results.  Here is the basic code....

    public class SimpleClass
    {
        /// <summary>
        /// Add two values
        /// </summary>
        /// <param name="first">first value to add</param>
        /// <param name="second">second value to add</param>
        /// <returns>sum of both values</returns>
        public int Add(int first, int second)
        {
            return first + second;
        }

        /// <summary>
        /// Divide two values
        /// </summary>
        /// <param name="first">first value to divide</param>
        /// <param name="second">second value to divide</param>
        /// <returns>division of both values</returns>
        public decimal Divide(int first, int second)
        {
            return first / second;
        }
    }

Lets get down to the testing.

First off all you need a class decorated with the attribute [TestFixture] this will tell NUnit GUI to run the test from the external program.  Here you can see a basic test thats you've probably see a few times before.

    [TestFixture]
    public class TestingExamples
    {
        [Test(Description="Basic Test")]
        public void SimpleClass_Test_A_Simple_Method()
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }
    }

It's saying pass the values 10 and 20 into the Add method and expect to get the result 30.  Simple really, and probably the type of test you'l want to write over and over again.  Howere there are other options available.

Repeat Test

        [Test(Description = "Repeat Test"), Repeat(30)]
        public void SimpleClass_Repeat_Test()
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }

By adding the Repeat(30) attribute to the test as shown this will run the test 30 times.  In this example it's not really a very useful test but if for example you want to test load on a server or perhaps populate a number of rows in a database it can be very useful.

Multipule Value Test

        [Test(Description="Multivalue Test")]
        [TestCase(10,20,30)]
        [TestCase(1,2,3)]
        [TestCase(7,6,13)]
        public void SimpleClass_TestCase_With_Many_Inputs(int
firstInput, int secondInput, int expectedResult)
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(firstInput, secondInput);
            Assert.IsTrue(result == expectedResult, "Result was not correct!");
        }

Here I'm calling the test 3 times but passing 3 different values and testing against 3 different results.  By using the [TestCase] attribute you can just add more and more values to the same test.

Expected Exception Test

        [Test(Description = "Expected Exception Test")]
        [ExpectedException(typeof(DivideByZeroException),
ExpectedMessage = "divide", MatchType = MessageMatch.Contains)]
        public void SimpleClass_TestCase_Divide_By_Zero()
        {
            SimpleClass simpleClass = new SimpleClass();
            decimal result = simpleClass.Divide(0, 0);
        }

Here is a divide test that throws a divide by Zero error.  By using the ExpectedException attribute we catch the error thrown by the .Net function and then checks it's the correct one, in this case System.DivideByZeroException.  It also checks the message text for the text "divide" and uses the MessageMatch.Contains attribute to indicate the text can exist anywhere in the error message.

Explicit

        [Test(Description = "Only Run when Explicitly chosen"), Explicit]
        public void SimpleClass_Explicit_Test_Of_Method()
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }

This is an interesting one for us in that it will only run when you "explicitly" select it to run using TestRunner or the Nunit GUI, if not it will be ignored during test runs.  You'd use this function if you wanted to have a UI test or specific test that won't run on the Build server.

MaxTime and TimeOut

        [Test(Description = "Maxtime Test"), MaxTime(20)]
        public void  SimpleClass_Max_Time_In_Mili_Seconds()
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }

        [Test(Description = "Timeout Test"), Timeout(20)]
        public void SimpleClass_Ensure_Long_Running_Process_Does_Not_Time_Out()
        {
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }

Timed tests are great for performance tests, here we specify that both tests need to run within 20 miliseconds.  What's the difference between them?  Well not a lot really so it's probably best to stick to Timeout and ignore MaxTime.

Platform

        [Test(Description = ".Net exclude test"), Platform(Exclude = "NET-2.0")]
        public void SimpleClass_Exclude_DotNet_Tests()
        {
            // Other options relevant to us
            // WinXP, Win2003Server, Vista, Net-1.1, Mono
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(10, 20);
            Assert.IsTrue(result == 30, "Result was not correct!");
        }

Probably not something we'd use very often but it may be useful in the future.  Here we specify that we this test should not be run under .Net 2.  Again the test is not important here what is important is that we can say things like only run a test on a Windows 2003 Server or only run the test on XP.

Random Values

        [Test(Description = "Random value generation test")]
        public void SimpleClass_Random_Values(
            [Values(10, 20, 30)] int firstValue,
            [Random(1, 50, 5)] int secondValue)
        {
            // run 15 times.. 3 values by 5 random numbers
            SimpleClass simpleClass = new SimpleClass();
            int result = simpleClass.Add(firstValue, secondValue);
            int testResult = firstValue + secondValue;
            Assert.IsTrue(result == testResult, "Result was not correct!");
        }

Finally sometimes you just can't be assed coming up with test data so in this case we use the [Random] attribute.  By saying [Random(1,50,5) int ]  I'm saying choose a number between 1 and 50 and run that test 5 times.  I've also added 3 additional [Values] 10,20 and 30 this means the test will run 15 times, i.e. 3 by 5