《软件工程》实验报告(一)——TDD测试驱动开发实验
一、实验名称
TDD测试驱动开发实验
二、实验目的
1)理解TDD测试驱动开发的思想
2)掌握TDD测试驱动开发的基本过程
三、实验内容和要求
1)阅读:Kent Beck 《测试驱动开发》
2)基于TDD开发一个判断字符串是IP4地址的功能
3)使用任何OO语言
4)使用xUnit测试框架
四、实验思路
IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a, b, c, d都是0~255(含0和255)之间的十进制整数。字符串是IP4地址的条件:
1. 字符串中有且只有3个分隔符“.”
2. 分隔符旁边的数字都在0~255之间
3. 字符串中除了4组数字和3个分隔符,没有任何其他字符
五、实验过程与结果
1. 编写测试用例
输入 | 预期结果 |
| 输入 | 预期结果 |
0.10.0.0 | 是IP4地址 | 1。2.3.4 | 不是IP4地址 | |
192.168.1.1 | 是IP4地址 | 12.34.56.67.78 | 不是IP4地址 | |
135.246.100.1 | 是IP4地址 | 00.1.1.1 | 不是IP4地址 | |
12.34. 45.56 | 不是IP4地址 | 1..2.3 | 不是IP4地址 | |
123.345.122.211 | 不是IP4地址 | a.1.1.1 | 不是IP4地址 |
2.修复测试缺陷
编写本程序存在的问题有:
①判断字符串中有且只有3个分隔符“.”
②判断分隔符旁边的数字都在0~255之间
③判断字符串中除了4组数字和3个分隔符,没有任何其他字符
3.编写代码使所用测试用例都能通过
#include <stdio.h>
#define true 1
#define false 0
typedef char bool;
bool checkIpv4(const char *ip)
{
printf("检验对象是:%s\n", ip);
if(NULL == ip)
{
return false;
}
const char *q = ip; //字串指针
unsigned short int s = 0, count = 0, digitNumber = 0; //s是字串转化为的整型,count是 . 的个数, digitNumber 是 . 之间的数量
bool hasZero = false;
// 开头有空格
while(' ' == *q)
{
q++;
}
while('\0' != *q)
{
if('.' == *q)
{
// . 前面没有任何值,则非法
if(digitNumber == 0)
{
return false;
}
s = 0;
digitNumber = 0;
count++;
hasZero = false;
q++;
continue;
}
// 值非法
if(*q < '0' || *q > '9')
{
// 结尾空格
if(' ' == *q && 3 == count)
{
const char *qq = q;
while(' ' == *qq)
{
qq++;
}
return '\0' == *qq;
}
else
{
return false;
}
}
int x = *q - '0';
s = s*10 + x;
// 0.0.0.0 合法, 00.0.0.0 不合法
if(0 == s)
{
if(hasZero)
{
return false;
}
else
{
hasZero = true;
}
}
if(s > 255)
{
return false;
}
digitNumber++;
q++;
}
return (3 == count);
}
int main(void)
{
{
char *ip[10]=
{
"0.10.0.0", "192.168.1.1",
"135.246.100.1", "12.34. 45.56", "123.345.122.211", "1。2.3.4",
"12.34.56.67.78", "00.1.1.1", "1..2.3", "a.1.1.1"
};
for(int i = 0; i < 10; i++)
{
if(checkIpv4(ip[i]))
printf("该地址是IPv4地址\n");
else
printf("该地址不是IPv4地址\n");
}
}
return 0;
}
4.测试结果
所有测试用例都能通过,可以实现判断一个字符串是否为IP4地址的功能。
5.优化代码结构
#include <stdio.h>
#define true 1
#define false 0
typedef char bool;
bool checkIpv4(const char *ip)
{
printf("检验对象是:%s\n", ip);
if(NULL == ip)
return false;
const char *q = ip; //字串指针
unsigned short int s = 0, count = 0, digitNumber = 0; //s是字串转化为的整型,count是 . 的个数, digitNumber 是 . 之间的数量
bool hasZero = false;
// 开头有空格
while(' ' == *q)
q++;
while('\0' != *q)
{
if('.' == *q)
{
// . 前面没有任何值,则非法
if(digitNumber == 0)
return false;
s = 0;
digitNumber = 0;
count++;
hasZero = false;
q++;
continue;
}
// 值非法
if(*q < '0' || *q > '9')
{
// 结尾空格
if(' ' == *q && 3 == count)
{
const char *qq = q;
while(' ' == *qq)
qq++;
return '\0' == *qq;
}
else
return false;
}
int x = *q - '0';
s = s*10 + x;
// 0.0.0.0 合法, 00.0.0.0 不合法
if(0 == s)
{
if(hasZero)
return false;
else
hasZero = true;
}
if(s > 255)
return false;
digitNumber++;
q++;
}
return (3 == count);
}
int main(void)
{
{
char *ip[10]=
{
"0.10.0.0", "192.168.1.1",
"135.246.100.1", "12.34. 45.56", "123.345.122.211", "1。2.3.4",
"12.34.56.67.78", "00.1.1.1", "1..2.3", "a.1.1.1"
};
for(int i = 0; i < 10; i++)
{
if(checkIpv4(ip[i]))
printf("该地址是IPv4地址\n");
else
printf("该地址不是IPv4地址\n");
}
}
return 0;
}
五、实验体会
TDD测试驱动开发有诸多优势:
1.引导程序员设计合理的功能粒度和易测的外部模块接口。
2.自动化测试,能够在保证质量的前提下进行重构,对代码进行修改后可以方便地运行单元测试,以保证代码没有改成屎。
3.测试用例可以作为api demo文档,团队内程序员问我某个工具类的API如何使用,我让他去看单元测试的API调用方法。
4.提高开发速度,虽然测试代码是业务逻辑代码量的2-3倍,但是减少了大量基本逻辑错误,减少了返工工作量;减少调试时间,把精力放在基本功能模块及其关联的交互上,而不从全局考虑功能。