Click here to Skip to main content
15,896,153 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.6K   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 DateTimeTests;

namespace RandomArray
{
  public static class Program
  {
    public static bool CalculateMilliSecOverflow(MTimeSpan ts)
    {
      // [ts.Milliseconds.Wrap, val.Overflow_ms.True]
      return ts.Milliseconds == MTimeSpan.TimeCategory.Wrap;
    }

    public static bool CalculateSecOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      //    dt.Second.{*} * [ts.Seconds.Wrap]
      // + [dt.Second.Max,  val.Overflow_ms] * ts.Seconds.{*}
      return ts.Seconds == MTimeSpan.TimeCategory.Wrap ||
             (dt.Second == MDateTime.TimeCategory.Max && val.Overflow_ms);
    }

    public static bool CalculateMinuteOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      //    dt.Minute.{*} * [ts.Minutes.Wrap]
      // + [dt.Minute.Max,  val.Overflow_sec] * ts.Minutes.{*}
      return ts.Minutes == MTimeSpan.TimeCategory.Wrap ||
             (dt.Minute == MDateTime.TimeCategory.Max && val.Overflow_sec);
    }

    public static bool CalculateHourOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      //    dt.Hour.{*} * [ts.Hours.Wrap]
      // + [dt.Hour.Max,  val.Overflow_min] * ts.Hours.{*}
      return ts.Hours == MTimeSpan.TimeCategory.Wrap ||
             (dt.Hour == MDateTime.TimeCategory.Max && val.Overflow_min);
    }

    public static bool CalculateDayOverflowOnCommonYear(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      //    [dt.Day.SecondLast, val.Overflow_hour.True ] * !ts.Days.{Zero, Year}
      //  + [dt.Day.Last,       val.Overflow_hour.False] * !ts.Days.{Zero, Year}
      //  + [dt.Day.Last,       val.Overflow_hour.True ] *  ts.Days.{*}
      if (dt.Day == MDateTime.DayCategory.SecondLast && val.Overflow_hour)
      {
        return !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
      }
      if (dt.Day == MDateTime.DayCategory.Last)
      {
        return val.Overflow_hour || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
      }
      return false;
    }

    public static bool CalculateDayOverflowOnLeapYear(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      // dt.(Month.{Feb} * Year.{LeapYear, LeapCentury})
      // * ( 
      //   val.Overflow_hour.{*} * { 
      //     [dt.Day.Last, ts.Days.Year],
      //     [dt.Day.SecondLast, ts.Days.YearAndOneDay]
      //   }
      //   + [val.Overflow_hour.True, dt.Day.SecondLast, ts.Days.Year]
      // )

      if (dt.Month != MDateTime.MonthCategory.Feb) return false;
      if (dt.Year != MDateTime.YearCategory.LeapYear && dt.Year != MDateTime.YearCategory.LeapCentury) return false;
      if (dt.Day == MDateTime.DayCategory.Last && ts.Days == MTimeSpan.DayCategory.Year) return true;
      if (dt.Day == MDateTime.DayCategory.SecondLast && ts.Days == MTimeSpan.DayCategory.YearAndOneDay) return true;
      if (dt.Day == MDateTime.DayCategory.SecondLast && ts.Days == MTimeSpan.DayCategory.Year && val.Overflow_hour) return true;

      return false;
    }

    public static bool CalculateMonthOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      // # Overflow condtions for Dec 30
      // [dt.Month.Dec, dt.Day.SecondLast, val.Overflow_day.True] * !ts.Days.{Zero, Year}
      // # Overflow condtions for Dec 31
      // + [dt.Month.Dec, dt.Day.Last] 
      // * (  [val.Overflow_day.False] * !ts.Days.{Zero, Year}
      //    + [val.Overflow_day.True ] *  ts.Days.{*})
      if (dt.Month != MDateTime.MonthCategory.Dec) return false;
      if (dt.Day == MDateTime.DayCategory.SecondLast)
      {
        return val.Overflow_day && !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
      }
      else if (dt.Day == MDateTime.DayCategory.Last)
      {
        return val.Overflow_day || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.Year);
      }
      return false;
    }

    public static bool CalculateYearOverflow(MDateTime dt, MTimeSpan ts, MValidate val)
    {
      //   [dt.Year.Max, val.Overflow_mon.False] * !ts.Days.{Zero, One}
      // + [dt.Year.Max, val.Overflow_mon.True ] *  ts.Days.{*}
      if (dt.Year != MDateTime.YearCategory.Max) return false;
      return val.Overflow_mon || !(ts.Days == MTimeSpan.DayCategory.Zero || ts.Days == MTimeSpan.DayCategory.One);
    }

    public static bool CheckConstraints(MDateTime dt, MTimeSpan ts)
    {
      // # Strength-2 constraints
      // { [dt.Millisecond.Min, ts.Milliseconds.Wrap] }, 
      // # Strength-3 constraints
      // { [dt.Second.Min,      ts.Milliseconds.NoWrap, ts.Seconds.Wrap],
      //   [dt.Minute.Min,      ts.Seconds.NoWrap,      ts.Minutes.Wrap],
      //   [dt.Hour.Min,        ts.Minutes.NoWrap,      ts.Hours.Wrap]
      // }) 
      if (dt.Millisecond == MDateTime.TimeCategory.Min && ts.Milliseconds == MTimeSpan.TimeCategory.Wrap) return false;
      if (dt.Second == MDateTime.TimeCategory.Min && ts.Milliseconds == MTimeSpan.TimeCategory.NoWrap && ts.Seconds == MTimeSpan.TimeCategory.Wrap) return false;
      if (dt.Minute == MDateTime.TimeCategory.Min && ts.Seconds == MTimeSpan.TimeCategory.NoWrap && ts.Minutes == MTimeSpan.TimeCategory.Wrap) return false;
      if (dt.Hour == MDateTime.TimeCategory.Min && ts.Minutes == MTimeSpan.TimeCategory.NoWrap && ts.Hours == MTimeSpan.TimeCategory.Wrap) return false;
      return true;
    }

    static void Main(string[] args)
    {
      const int trials = 1000;
      int countRejected = 0;
      Randomizer randomizer = new Randomizer();
      for (int i = 0; i != trials; ++i)
      {
        MDateTime dt = new MDateTime();
        MTimeSpan ts = new MTimeSpan();
        randomizer.RandomizeAllEnums(dt);
        randomizer.RandomizeAllEnums(ts);

        if (CheckConstraints(dt, ts))
        {
          MValidate val = new MValidate();

          val.Overflow_ms = CalculateMilliSecOverflow(ts);
          val.Overflow_sec = CalculateSecOverflow(dt, ts, val);
          val.Overflow_min = CalculateMinuteOverflow(dt, ts, val);
          val.Overflow_hour = CalculateHourOverflow(dt, ts, val);
          val.Overflow_day = CalculateDayOverflowOnCommonYear(dt, ts, val) || CalculateDayOverflowOnLeapYear(dt, ts, val);
          val.Overflow_mon = CalculateMonthOverflow(dt, ts, val);
          val.Overflow_year = CalculateYearOverflow(dt, ts, val);

          DateTimeTests.DateTimeTests.AddTimeSpan(dt, ts, val);
        }
        else
        {
          ++countRejected;
          --i;
        }
      }
      Console.WriteLine("{0} tests executed successfully", trials);
      Console.WriteLine("Created {0} random samples (with {1} samples rejected due to constraints)", trials + countRejected, countRejected);
    }
  }
}

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