《软件工程》实验报告(三)——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地址的条件:
- 字符串中有且只有3个分隔符“.”
- 分隔符旁边的数字都在0~255之间
- 字符串中除了4组数字和3个分隔符,没有任何其他字符
五、 编写实验用例
输入 | 结果 |
---|---|
0.10.0.0 | true |
192.168.1.1 | true |
135.246.100.1 | true |
12.34. 45.56 | false |
1。2.3.4 | false |
12.34.56.67.78 | false |
123.345.122.211 | false |
a.1.1.1 | false |
改进为:
输入 | 结果 |
---|---|
0.10.0.0 | true |
null | false |
135.246.100 | false |
12.34. 45.56 | false |
123.345.122.211 | false |
1。2.3.4 | false |
12.34.56.67.78 | false |
00.1.1.1 | false |
1…2.3 | false |
a.1.1.1 | false |
六、 编写代码进行测试
public class TDD {
private String ipString;
public TDD(String ipString) {
this.ipString = ipString;
}
public static void main(String[] args) {
TDD[] tdds = new TDD[10];
tdds[0] = new TDD("0.10.0.0");
tdds[1] = new TDD(null);
tdds[2] = new TDD("135.246.100");
tdds[3] = new TDD("12.34. 45.56");
tdds[4] = new TDD("123.345.122.211");
tdds[5] = new TDD("1。2.3.4");
tdds[6] = new TDD("12.34.56.67.78");
tdds[7] = new TDD("00.1.1.1");
tdds[8] = new TDD("1..2.3");
tdds[9] = new TDD("a.1.1.1");
boolean[] answers = new boolean[10];
for (int i = 0; i < 10; i++) {
answers[i] = tdds[i].isIP4();
}
for (int i = 0; i < 10; i++) {
System.out.println(answers[i]);
}
}
public boolean isIP4(){
//字符串为空
if (ipString == null){
return false;
}
int ipLength = ipString.length();
//字符串长度小于7
if (ipLength < 7){
return false;
}
int num = 0;
int dotCount = 0;
boolean isDotCountChanged = true;
int stringCount = 0;
int midNumber = 0;
int numNow = 0;
int index = 0;
while (index < ipLength){
numNow = ipString.charAt(index);
if (numNow == '.'){
if (midNumber == 0){
return false;
}
num = 0;
midNumber = 0;
dotCount++;
if (dotCount > 3){
return false;
}
isDotCountChanged = true;
}
else if (numNow <= '9' && numNow >= '0'){
if (isDotCountChanged){
stringCount++;
if (stringCount > 4){
return false;
}
isDotCountChanged = false;
}
if (num == 0 && midNumber > 0 && numNow == '0'){
return false;
}
num = num*10+(numNow-48);
if (num > 255 || num < 0){
return false;
}
midNumber++;
}
else {
return false;
}
index++;
}
if (dotCount == 3 && stringCount == 4){
return true;
}
else {
return false;
}
}
}
结果
true
false
false
false
false
false
false
false
false
false
对代码进行重构:
将中间变量放入一个类中,删去冗余代码
public class TDD {
private String ipString;
public TDD(String ipString) {
this.ipString = ipString;
}
public static void main(String[] args) {
TDD[] tdds = new TDD[10];
tdds[0] = new TDD("0.10.0.0");
tdds[1] = new TDD(null);
tdds[2] = new TDD("135.246.100");
tdds[3] = new TDD("12.34. 45.56");
tdds[4] = new TDD("123.345.122.211");
tdds[5] = new TDD("1。2.3.4");
tdds[6] = new TDD("12.34.56.67.78");
tdds[7] = new TDD("00.1.1.1");
tdds[8] = new TDD("1..2.3");
tdds[9] = new TDD("a.1.1.1");
boolean[] answers = new boolean[10];
for (int i = 0; i < 10; i++) {
answers[i] = tdds[i].isIP4();
}
for (int i = 0; i < 10; i++) {
System.out.println(answers[i]);
}
}
public boolean isIP4(){
//字符串为空
if (ipString == null){
return false;
}
int ipLength = ipString.length();
//字符串长度小于7
if (ipLength < 7){
return false;
}
MidVariable midVariable = new MidVariable();
while (midVariable.index < ipLength){
midVariable.numNow = ipString.charAt(midVariable.index);
if (midVariable.numNow == '.'){
if (midVariable.midNumber == 0){
return false;
}
midVariable.num = 0;
midVariable.midNumber = 0;
midVariable.dotCount++;
if (midVariable.dotCount > 3){
return false;
}
midVariable.isDotCountChanged = true;
}
//两个.之间的数值是否合法
else if (midVariable.numNow <= '9' && midVariable.numNow >= '0'){
if (midVariable.isDotCountChanged){
midVariable.stringCount++;
if (midVariable.stringCount > 4){
return false;
}
midVariable.isDotCountChanged = false;
}
if (midVariable.num == 0 && midVariable.midNumber > 0 && midVariable.numNow == '0'){
return false;
}
midVariable.num = midVariable.num*10+(midVariable.numNow-48); //字符'0'的整数值为48
if (midVariable.num > 255 || midVariable.num < 0){
return false;
}
midVariable.midNumber++;
}
else {
return false;
}
midVariable.index++;
}
if (midVariable.dotCount == 3 && midVariable.stringCount == 4){
return true;
}
else {
return false;
}
}
}
public class MidVariable {
int num = 0; //两个.之间的0~255数字
int dotCount = 0; //.的个数之和
boolean isDotCountChanged = true; //.的数量是否增加了
int stringCount = 0; //两个.之间的0~255数字的数量是否增加了
int midNumber = 0; //两个.之间的0~9数字有多少个
int numNow = 0; //当前下标指向的字符
int index = 0; //当前的下标
}
七、 实验总结
TDD会带来的好处可能不会马上呈现,但是你在某个时候一定会发现,这些好处包括:
-
更清晰的代码 — 只写需要的代码
-
更好的设计
-
更出色的灵活性 — 鼓励程序员面向接口编程
-
更快速的反馈 — 不会到系统上线时才知道bug的存在
需求向来就是软件开发过程中感觉最不好明确描述、易变的东西。测试驱动开发就是通过编写测试用例,先考虑代码的使用需求,通过编写这部分代码的测试用例,对其功能的分解、使用过程、接口都进行了设计。而且这种从使用角度对代码的设计通常更符合后期开发的需求,可测试的要求,对代码的内聚性的提高和复用都非常有益。