Archive

Archive for February, 2009

Simplify Time Measurement in Tests and Debug Code

February 23rd, 2009

A simple helper class I derived from a more generic pattern: For debugging and testing, I quite often want to measure the time used for a given process. Usually, this looks somewhat like this:

 

public void TestElapsedTime()
{
  DateTime start = DateTime.Now;

  //do some work

  DateTime end = DateTime.Now;
  double elapsedTime = end.Subtract(start).TotalMilliseconds;
  Console.Out.WriteLine("Work took {0} milliseconds", elapsedTime);
}

 

However: The code above, while being pretty simple, can be easily wrapped into a generic helper class:

 

/// <summary>
/// A guard that can be used to measure the time
/// used for a given process by simply wrapping it
/// in a using statement.
/// </summary>
public class TimeGuard : IDisposable
{
  private readonly Action<double> action;
  private readonly DateTime startTime;


  /// <summary>
  /// Creates the guard with a given action that receives the
  /// elapsed time in milliseconds.
  /// </summary>
  /// <param name="setDelta">The action that is being invoked
  /// with time (in milleconds) that was taken between construction
  /// of this instance until disposal.</param>
  /// <exception cref="ArgumentNullException">If <paramref name="setDelta"/>
  /// is a null reference.</exception>
  public TimeGuard(Action<double> setDelta)
  {
    if (setDelta == null) throw new ArgumentNullException("setDelta");
    
    action = setDelta;
    startTime = DateTime.Now;
  }


  /// <summary>
  /// Calculates the elapsed time since construction
  /// and submits the delta to the <see cref="action"/>
  /// action.
  /// </summary>
  public void Dispose()
  {
    var now = DateTime.Now;
    action(now.Subtract(startTime).TotalMilliseconds);
  }
}

 

Using the TimeGuard class, I can perform time measurements without having to deal with DateTime instances and the calculation of the elapsed time at all. Two samples:

 

public void TestElapsedTime()
{
  double elapsedTime = 0;
  using (new TimeGuard(t => elapsedTime = t))
  {
    //do some work
  }

  Console.Out.WriteLine("Work took {0} milliseconds", elapsedTime);
}

 

[Test]
public void TestElapsedTime()
{
  using (new TimeGuard(t => Assert.Less(t, 500)))
  {
    //do some work here that should take less than 500 ms
  }
}

 

Apart from providing cleaner code, I also prefer this approach because it encapsulates time measurement functionality in a single class and simplifies adjustments, like using a different pattern to retrieve time stamps, or using the StopWatch class to get a more accurate measurement (thanks to Simone Chiaretta for the hint).

Author: Categories: C#, Testing Tags:

Simple Extension Method to Evaluate Listings For a Match

February 4th, 2009

I’m currently dealing with a system that switches between different states, which require evaluations that look similar to the snippet below:

 

//check status flags
TestStatus status = GetStatus();
if (status == TestStatus.Preparing ||
    status == TestStatus.Running ||
    status == TestStatus.PostDelay)
{
  ...
}

 

Given the fact that I’m having lots of states, I had to produce pretty nasty code, so I wrote that handy little extension method that takes care of the issue once and for all:

Edit (2009.02.08): Returning false for null values which allows to submit null references without exception.

 

/// <summary>
/// Checks a list of candidates for equality to a given
/// reference value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The evaluated value.</param>
/// <param name="candidates">A liste of possible values that are
/// regarded valid.</param>
/// <returns>True if one of the submitted <paramref name="candidates"/>
/// matches the evaluated value. If the <paramref name="candidates"/>
/// parameter itself is null, too, the method returns false as well,
/// which allows to check with null values, too.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
/// is a null reference.</exception>
public static bool Is<T>(this T value, params T[] candidates)
{
  if (candidates == null) return false;

  foreach (var t in candidates)
  {
    if (value.Equals(t)) return true;
  }

  return false;
}

 

Using this “Is” extension, I can now write the above code like this:

 

if (status.Is(TestStatus.Preparing, TestStatus.Running, TestStatus.PostDelay)
{
  ...
}

 

Of course, this is not limited to Enums but works with everything that supports the Equals operator:

string name = ...
if (name.Is("foo", "bar"))
{
  //foobar!
}
Author: Categories: C# Tags: