Click here to Skip to main content
15,881,559 members
Articles / DevOps / Unit Testing

All About Test Part 1 - Choosing Your Tests

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
21 Jan 2013CPOL21 min read 19.4K   147   12  
Beyond basic unit tests, how do you choose your tests and when are you done?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QgOne.Core;

namespace DateTimeTests
{
  [Settable, Serializable]
  public class MTimeSpan
  {
    #region Categories

    public enum DayCategory { Zero, One, Year, YearAndOneDay }
    public enum TimeCategory
    {
      /// <summary>
      /// A value that causes no wrap when added to DateTime.Millisecond, Second, Minute or Hour
      /// </summary>
      NoWrap,

      /// <summary>
      /// A value that causes a wrap when added to DateTime.Millisecond, Second, Minute or Hour are in category Max
      /// </summary>
      Wrap
    }

    #endregion Categories

    #region Factors

    public DayCategory Days { get; set; }
    public TimeCategory Hours { get; set; }
    public TimeCategory Minutes { get; set; }
    public TimeCategory Seconds { get; set; }
    public TimeCategory Milliseconds { get; set; }

    #endregion Factors

    #region Counts

    public int MonthDays
    {
      get
      {
        if (Days == DayCategory.Zero || Days == DayCategory.Year)
        {
          return 0;
        }
        else
        {
          return 1;
        }
      }
    }

    public int Months { get { return 0; } } // Hardcoded to 0 because no category yields a different value

    public int Years
    {
      get
      {
        return Days == DayCategory.Year || Days == DayCategory.YearAndOneDay ? 1 : 0;
      }
    }

    #endregion Counts

    #region Resolve

    public int ResolveDays(int daysInYear)
    {
      switch (Days)
      {
        case DayCategory.Zero:
          return 0;
        case DayCategory.One:
          return 1;
        case DayCategory.Year:
          return daysInYear;
        case DayCategory.YearAndOneDay:
          return daysInYear + 1;
      }

      throw new ArgumentException(string.Format("Cannot resolve days for {0}", Days));
    }

    public int ResolveTimeCategory(int target, bool carryFromPrevious, TimeCategory tc, int minValue, int maxValue)
    {
      if (carryFromPrevious)
      {
        ++target;
      }

      if (target > maxValue)
      {
        // Can happen e.g. if Minute is 59 and carryFromPreviosu is true
        return 0;
      }

      Random prng = new Random();
      if (tc == TimeCategory.NoWrap)
      {
        return prng.Next(target, maxValue) - target; // A random value that does not cause a wrap
      }
      else if (tc == TimeCategory.Wrap)
      {
        if (target == 0)
        {
          throw new ArgumentException("Not possible to derive time part that causes 0 to wrap");
        }
        return prng.Next(maxValue + 1, target + maxValue) - target; // A random value that causes a wrap
      }

      throw new ArgumentException("Unknown time category");
    }

    public void Resolve(MDateTime mdt, MValidate val)
    {
      DateTime target = mdt.Value;

      int days = ResolveDays(mdt.DaysInYear);
      int hours = ResolveTimeCategory(target.Hour, val.Overflow_min, Hours, 0, 23);
      int mins = ResolveTimeCategory(target.Minute, val.Overflow_sec, Minutes, 0, 59);
      int secs = ResolveTimeCategory(target.Second, val.Overflow_ms, Seconds, 0, 59);
      int msecs = ResolveTimeCategory(target.Millisecond, false, Milliseconds, 0, 999);

      Value = new TimeSpan(days, hours, mins, secs, msecs);
    }

    #endregion Resolve

    /// <summary>
    /// Resolve must be called before using this property.
    /// </summary>
    public TimeSpan Value { get; private set; }

  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Denmark Denmark
I started programming as a kid and went through basic, C and assembler. I got a MSc.CS from University of Aarhus in 1998 and have maintained an interest for computer science ever since, that I enjoy applying to the problems I come across. I have worked in different roles as a programmer, architect, project manager and consulting in many different areas including databases, cryptography, server architecture and distributed systems. I am currently focussing on the testing done during development and seek to improve this through a combination of approach, skill and technology.

Comments and Discussions