C 如何为细微错误设计软件测试
这是一个超级简单的例子,在这里用C来说明一个微妙的错误,我不知道如何通过测试将其暴露为bug 考虑:C 如何为细微错误设计软件测试,c,testing,C,Testing,这是一个超级简单的例子,在这里用C来说明一个微妙的错误,我不知道如何通过测试将其暴露为bug 考虑: #include <stdio.h> int main() { int a; int b; int input; printf("Enter 1 or 2: "); scanf("%d", &input); switch(input) { case 1: a = 10; /* ERROR HERE, I FORGOT A B
#include <stdio.h>
int main()
{
int a;
int b;
int input;
printf("Enter 1 or 2: ");
scanf("%d", &input);
switch(input) {
case 1:
a = 10;
/* ERROR HERE, I FORGOT A BREAK! */
case 2:
b = 20;
break;
default:
printf("You didn't listen!\n");
return 1;
break;
}
if(input == 1) {
b = 30;
printf("%d, %d\n", a, b);
} else {
printf("%d\n",b);
}
return 0;
}
#包括
int main()
{
INTA;
int b;
int输入;
printf(“输入1或2:”);
scanf(“%d”,输入(&I));
开关(输入){
案例1:
a=10;
/*这里出错了,我忘记休息了*/
案例2:
b=20;
打破
违约:
printf(“您没有听!\n”);
返回1;
打破
}
如果(输入=1){
b=30;
printf(“%d,%d\n”,a,b);
}否则{
printf(“%d\n”,b);
}
返回0;
}
如代码中所述,缺少一个中断
,因此当输入1时,将进入案例2。但是1的输出没有反映这一点,因为它稍后会覆盖b
。因此,我们可以设计的所有测试,比如从集合{1,2,10}
中输入一个数字,都会得到正确的输出
实际上,开关
内的分配可能非常昂贵,因此此错误可能非常昂贵。但是,假设它是从第一天开始这样写的,没有基准可以看出成本高于预期
那么,我们可以做些什么来消除这些错误呢?有没有办法设计测试用例以在生产软件中公开它
编辑
所以我想我并不完全清楚——我用C写它是为了说明遇到的问题类型,但实际上它并不特定于C。我想指出的是,代码进入了我们从未打算进入的部分(在这种情况下,是因为一个被遗忘的中断,来说明这一点)。我的实际案例是一个有700000行的Fortran代码,它正在进入我们从未打算进入的分支,因为糟糕的if/开关设计从语言角度来看是合法的,但可能非常昂贵
是否有可能设计一个测试或查看来自某个工具的一些数据,这些数据会告诉我们它将进入不应该进入的分支?我在所有案例中打印“我不应该在这里!”时发现了一个错误,并看到它被打印出来,一定有比随机查看和打印语句更好的方法。您可以为switch语句定义编码约定,这样每个分支都会施加一种特殊状态。就像一个变量被赋值一样。例如:
switch (v) {
case 1:
vcheck = 1;
...
break;
case 2:
vcheck = 2;
...
break;
}
并在测试用例中测试vcheck
除此之外,您还可以使用对验证执行静态代码分析的工具,并将它们应用到构建过程中。他们会引起一些想法…:-)
最后,(我最喜欢的)您可以编写一个脚本,用于检查此类情况并再次发出警告。您可以为switch语句定义编码约定,以便每个分支都会施加特殊状态。就像一个变量被赋值一样。例如:
switch (v) {
case 1:
vcheck = 1;
...
break;
case 2:
vcheck = 2;
...
break;
}
并在测试用例中测试vcheck
除此之外,您还可以使用对验证执行静态代码分析的工具,并将它们应用到构建过程中。他们会引起一些想法…:-)
最后,(我最喜欢的)您可以编写一个脚本来检查此类情况并再次发出警告。情况1的正确状态是不会设置b
检查是否设置了b
如果以后要设置b,可能需要将代码分解成更小的段来测试这一点,但这就是良好的模块化
您似乎在问“如何测试不稳定的代码?”。答案是,编写可测试代码需要技巧和计划,不能只是事后的想法
web上有很多东西可以帮助您编写可测试代码:
情况1的正确状态是不会设置b
检查是否设置了b
如果以后要设置b,可能需要将代码分解成更小的段来测试这一点,但这就是良好的模块化
您似乎在问“如何测试不稳定的代码?”。答案是,编写可测试代码需要技巧和计划,不能只是事后的想法
web上有很多东西可以帮助您编写可测试代码:
如果输入==1
并且您在输出上看到b=30
,您就知道出了问题。另外,请记住在else子句中,在阅读b之前,您应该先给b写一些东西。在default:
(例如,input==100
)的情况下,您可能会在没有正确设置的情况下从某个位置读取
此外,如果你负担得起的话,代码审查应该会对找到类似的东西有很大帮助。如果input==1
并且你在输出上看到b=30
,你就知道出了问题。另外,请记住在else子句中,在阅读b之前,您应该先给b写一些东西。在default:
(例如,input==100
)的情况下,您可能会在没有正确设置的情况下从某个位置读取
此外,如果你能负担得起的话,代码审查应该对找到类似的东西有很大帮助。对于你的具体例子,从定义上讲,这绝不是一个错误/bug。在语言中,需要的是突破的可能性。如果你想禁止某些危险的语言特性,那么这是一条路要走
为了避免完全不可预见的错误,有一条规则:总是防御性地编写代码,并使用assert
s(您可以将它们放在任何地方)。对于您的特定示例,从定义上讲,这决不是错误/bug。在语言中,需要的是突破的可能性。如果你想禁止某些危险的语言特性,那么这是一条路要走
为了避免完全不可预见的错误,有一条规则:总是防御性地编写代码,并使用assert
s来放置它们。为什么我会问这个错误?使用任何类型的黑盒测试代码都有效。因此,如果唯一的需求