January 25, 2009

WinTask - The Next Date Test

In Chapter 5 of the terrific book "How We Test Software At Microsoft" by Alan Page, Ken Johnston and Bj Rollison, is one of the best discussions about Equivalence Class Partitioning and Boundary Value Analysis I have ever read.

As part of this discussion, Bj Rollison introduces an example application he calls The Next Date program.  (Bj tells me that the concept for the Next Date problem is from Paul C. Jorgensen’s book, “Software Testing: A Craftsman’s Approach” which is another fine book on software testing.)

This program is reproduced here as a WinTask script.

If you compile this script to a .rob file, and give the new or prospective tester a copy of WinTask and the .rob file, he can try testing the program for himself, using test cases he has devised.

You may even choose to intentionally create a buggy version of this script, to see if the new tester can find all of the bugs.




'
' NextDate - Demonstrates testing a simple application
'    using Equivalence Class Partitioning
'    and Boundary Value Analysis
'
' Author: Joe Strazzere
'
' Adapted from "How We Test Software at Microsoft"
' - Alan Page, Ken Johnston, Bj Rollison
'

'
' Here is where the NextDate function is implemented
' It would be simple to introduce intentional errors here
'
Function NextDate$(mm$,dd$,yyyy$)
mm=Val(mm$)
dd=Val(dd$)
yyyy=Val(yyyy$)
 If (Len(mm$) > 2) or (Len(dd$) > 2) or (Len(yyyy$) > 4) Then
  NextDate$="Invalid Date: ["+mm$+"/"+dd$+"/"+yyyy$+"]"
 Else
  If (yyyy < 1582) or (yyyy > 3000) Then
   NextDate$="Invalid Date: ["+mm$+"/"+dd$+"/"+yyyy$+"]"
  Else
   If (dd > 31) Then
    NextDate$="Invalid Date: ["+mm$+"/"+dd$+"/"+yyyy$+"]"
   Else
    If (mm > 12) Then
     NextDate$="Invalid Date: ["+mm$+"/"+dd$+"/"+yyyy$+"]"
    Else
     ' Special Date range
     ' the dates 10/5/1582 through 10/14/1582 are invalid
     ' (see page 85 in HWTSAM)
     If (mm = 10) and (dd >= 5) and (dd <= 14) and (yyyy = 1582) Then
      NextDate$="Invalid Date: ["+mm$+"/"+dd$+"/"+yyyy$+"]"
     Else
      ' Special Date range
      ' the day after 10/4/1582 is 10/15/1582
      ' (see page 85 in HWTSAM)
      If (mm = 10) and (dd = 4) and (yyyy = 1582) Then
       NextDate$="The next date is: 10/15/1582"
      Else
       NextDate$="The next date is: "+DateToDate$("d",1,mm$+"/"+dd$+"/"+yyyy$)
      EndIf
     EndIf
    EndIf
   EndIf
  EndIf
 EndIf
EndFunction

'
' Handle unexpected errors and DateToDate errors here
'
Sub error_proc()
 Text2$="Invalid Date: ["+Edit1$+"/"+Edit2$+"/"+Edit3$+"]"
EndSub

OnAction Error
 DoSub error_proc
EndAction

BEGINDIALOG Dialog 347, 362, 350, 220
CAPTION "Next Date"
 TEXT "Enter a date, then click OK to analyze, or Cancel to quit.", 31, 18
 TEXT "Month", 43,62
 TEXT "Day", 133,62
 TEXT "Year", 223,62
 EDITTEXT Edit1$, 40, 82, 50, 20
 TEXT "/", 105, 85
 EDITTEXT Edit2$, 130, 82, 50, 20
 TEXT "/", 195, 85
 EDITTEXT Edit3$, 220, 82, 50, 20
 TEXT Text1$, 40, 115
 DEFPUSHBUTTON "OK", btnOK, 137, 157, 75, 23
 PUSHBUTTON "Cancel", btnCancel, 217, 157, 75, 23
ENDDIALOG

'
' Instructions
'
Instr$=""
Instr$=Instr$+"The NextDate program takes three integer inputs that represent a specific"+CRLF
Instr$=Instr$+"month, day, and year in the Gregorian calendar and returns the next"+CRLF
Instr$=Instr$+"Gregorian calendar date in the month/day/year format."+CRLF
Instr$=Instr$+CRLF
Instr$=Instr$+"The algorithm to determine the next date is based on the Gregorian calendar,"+CRLF
Instr$=Instr$+"which is commonly used throughout the world today"+CRLF
Instr$=Instr$+CRLF
Instr$=Instr$+"The output is always in the m/d/yyyy format regardless of the user's locale"+CRLF
Instr$=Instr$+"setting (meaning the output is not culture sensitive)."+CRLF
Instr$=Instr$+CRLF
Instr$=Instr$+"The valid range for input is 1/1/1582 through 12/31/3000"

MsgBox(Instr$,64,"NextDate")

'
' Initial Display
'
Text1$=""
CallDialog Dialog,"Next Date"

'
' Subsequent Display
'
While btnOK = 1
 Text2$=""
 Text1$=NextDate$(Edit1$,Edit2$,Edit3$)
 If Text2$ <> "" Then
  Text1$=Text2$
 EndIf
 CallDialog Dialog,"Next Date"
Wend