|
为什么有可能利用测试确定程序中的错误呢?为了测试程序的性能,你不得不对你的程序 测试每一种输入数据或输入数据的组合。即使对一个简单的程序,这样的工作也令人难以容忍。 例如,你的程序接收人名、地址、电话号码并将其存在一个文件中。这是一个简单的程序,并 且比任何让你厌烦的程序都要简单。进一步假定每个可能的名字和地址是 20 个字符的长度,并 且它们要用到 26 个可能的字符。以下是可能的输入数据量: 名字 2620(20 个字符,每个字符有 26 种可能选择) 地址 2620(20 个字符,每个字符有 26 种可能选择) 电话号码 1010(10 个数字,每个数字有 10 种可能选择) 总的可能 =2620*2620*1010=1066 即使是这样较小输入量,你也将有 1066 种测试用例。如果诺亚走出其方舟并以每秒 1 兆次 的速度对程序进行测试,他即使到现在也才完成了全部工作量的 l%。显然,如果你增大实际数 据量,对全部可能性进行测试几乎是不可能的。 不完全测试 对各种可能全部进行测试是不可能的,实际说来,测试的艺术在于从所有测试用例中找出 最能发现错误的示例来。在 10 种可能测试示例中,只有少部分可能发现错误。你应侧重于从所 有测试示例中找出能提示不同点的用例,而不是那些不断地重复着的用例。 当你计划测试时,你应排除那些没有告诉你任何新东西的用例,这就是说,此时对新数据 的测试将不会产生错误。 人们已提出了不少有效的非实例测试法,下文将讨论其中的一些方法。 善于结构的测试 尽管其名字是粗糙的,基于结构的测试,其实是一个简单概念。其意思是你应对你程序中 的每一条语句至少测试一次,如果本语句是一条逻辑语句,通常是用 if 或 while,你就应根据 if 或 while 表达式中的复杂性仔细测试,这样才能确保每条语句都经过了测试。确保所有语句 都经过测试的最简单的方法是由程序计算路径数,然后设计最少数量的测试用例,以确保所有 路径都得到了测试。你可能听说过“代码覆盖”测试或“逻辑覆盖”测试;它们都是使你的测 试程序中所有路径的方法。由于这两种方法覆盖了所有路径,它们和基于结构的测试是相似的, 但是这二种方法覆盖所有路径时并不使用最小的测试用例集。如果你使用代码覆盖或逻辑覆盖 方法,你所需的测试用例可能比你用基于结构的测试所需的测试用例要多。 你可用表 25-1 所给出的方法计算所需的最少测试用例数。 表 25-l 确定基于结构的测试方法所需的测试用例 1.由程序的第一条直接路径开始,设定计数值为 1。 2.每遇到下一个关键词或其等价词: if,while,repeat,for,and 和 or 计数值加 1。 3.在 case 语句中每遇到一个 case, if 数值加 1。如果 case 语句中不含缺省语句,计数值再加 1。
以下是一个例子: 计算路径数目的一个简单的 Pascal 程序例子: Statement1; ――开始计数 1 Statement2; if X < 10 then ――遇到 if 计数 2 begin Statement3; End;1 Statement4; 本例中,你一开始将计数置为 1,在遇到 if 语句后计数值变为 2,这意味着你至少需要 2 个用例以便覆盖程序中的所有路径。在以上例子中,你应有以下示例: · 受 if 控制的语句得到执行(X<10) · 不受 if 控制的语句得到执行:(X>=10) 代码例子还应更实际一点,以便对测试工作有一个清晰的了解。例子中实际还包括有缺陷 的代码。 下面的程序稍复杂一点。在本章以后都使用这个例子并且它可能有一些错误。 确定基于结构的测试所需测试用例的一个 Pascal 例子; 1 { Compute Net Pay} 程序开始,计数 1 2 3 TtlWithholdings := 0; 4 5 for ID := 1 to NumEInPloyees ——for,计数 2 6 begin 7 8 { compute social security withholding, if below the maximum } 9 if(Employee[ID].SSWithheld<MAX_SOCIAL_SECURITY )then ——if,计数 3 10 begin 11 SocialSecurity := ComputeSocialSecurity(Employee[ID]) 12 end; 13 14 {set default to no retirement contribution} 15 Retirement := 0; 16 17 {determine discretionary employee retirement contribution} 18 if(Employee[ID].WantsRetirement)and ——if,计数 4 and,计数 5 19 (EligibleFotRetirement( Employee[ID])) then 20 begin 21 Retirement := GetRetirement(Employee[ID]); 22 end; 23 24 GrossPay := ComputeGrossPay(Employee[ID]);
25 26 { determine IRA contribution } 27 IRA := 0; 28 if( EligibleForIRA( EmPloyee[ID]) ) then ——if,计数 6 29 begin 30 IRA := IRAContribution(Employee[ID],Retirement,GrossPay) 31 end; 32 33 { make weekly paycheck} 34 Withholding := ComputeWithholding(Employee[ID]); 35 NetPay := GrossPay-Withholding-Retirement- 36 SocialSecurity-IRA; 37 PayEmployee(EmPloyee[ID],NetPay); 38 39 { add this employee’s paycheck to total for accounting} 40 TtlWithholdings := TtlWithholdingst 十 Withholding; 41 TtlSocialb [1] [2] [3] [4] 下一页
|