测试驱动开发

测试驱动开发理念深入人心,作为测试驱动的一个经典框架Junit值得了解。是个开源的单元测试框架,一个Junit测试应包含如下几个重要的部分,开发代码、测试代码、测试工具。单元测试长期忽视,即使现在很多公司推出要极限编程,但是都是外部推动性的,真正发挥自我能动性写单元测试的能有几个人呢?这种好的编程思想和编程习惯要从今天就要养成。但是测试代码仍然要人工编写,太麻烦了!!编程时候打印trace调试、利用断言、打印中间值、编写测试代码都是极为麻烦,自动化水平太低,自动化测试才是真正的解决之道。自动化单元测试框架xUnit,一定要看看的!!

测试驱动开发的精髓:将测试方案设计工作提前,在编写代码之前先做这项工作;从测试的角度来验证设计,推导设计;同时将测试方案作为行为的准绳,有效的利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的小步快走”.

 

软件开发方法学泰斗    Kent Beck  <模式、极限编程和测试驱动开发> 《测试驱动开发》、<敏捷软件开发>、《拥抱变化:解析极限编程》

 

 

实践测试驱动开发 
  下面,我就结合一个实际的小例子,来说明如何进行"测试驱动开发"。本实例在J2SE SDK 1.4.2环境下开发,以及配套工具JUnit 3.8.1 


  任务简述 


  队列是一种在程序开发中十分常用的数据结构,在此我就以编写一个实现队列功能的类--Queue为例进行说明。该类将实现以下基本运算: 
  判断队列是否为空:empty()
 
  插入队列(即在队列未尾增加一个数据元素):inqueuex
 
  出队列(也就是将队列首数据元素删除):outqueue()
 
  取列头(也就是读者队列首数据元素的值):gethead()
 
  清空队列(也就是将队列的所有数据元素全删除): clear()
 
  查询x在队列中的位置:searchx
 
  测试案例分析
 
  在测试驱动开发实践中,第一步就是考虑测试方案,通过分析该类的功能,我们可以得到以下测试案例:
 
  1 队列为空测试
 
   TC01 队列新建时,应为空;
 
   TC02 清空队列后,应为空;
 
   TC03 当出队列操作次数与插入队列操作次数一样时,应为空;
 
  2 插入队列测试:
 
   TC04 插入队列操作后,新数据元素将插入在队列的未尾;
 
   TC05 插入队列操作后,队列将一定不为空;
 
  3 出队列测试
 
   TC06 出队列操作后,第一个数据元素将被从队列中删除;
 
  4 取队头测试
 
   TC07 取队头操作将获得队列中的第一个数据元素。
 
  5 清空队列测试
 
   TC08 清空队列操作后,队列将为空队列;
 
  注: 此处为了讲解的方便,并未将所有的测试用例都列出,同时也选择了一些十分简单的测试用例。
 
  第一次迭代
 
  我们首先编写第一个测试代码,这一测试代码只考虑了测试案例TC01 也就是保证新建的队列为空:
 
import junit.framework.*; 
//
每个使用JUnit编写的测试代码都应该包括本行

public class testQueue extends TestCase 
//
创建一个测试用例,继承TestCase
{
protected Queue q1;
public static void main (String[] args)
{
junit.textui.TestRunner.run (suite()); 
//
执行测试用例


protected void setUp() //
环境变量准备

q1= new Queue(); 

public static Test suite() //
通用格式,指定测试内容

return new TestSuite(testQueue.class); 

public void testEmpty() //
以下每个方法就是一个测试

assertTrue(q1.empty()); 
//
当队列新建时,应为空-TC01
}

  安装JUnit十分简单,只需在www.junit.org中下载最新的软件包(ZIP格式), 然后将其解压缩,并且将"JUnit安装目录/junit.jar" 以及"JUnit安装目录"都加到系统环境变量CLASSPATH中去即可。
 
  执行套件可以像上述程序一样在main方法中使用,也可以直接在命令行调用:java junit.textui.TestRunner 测试类名(文本格式)、java junit.awtui.TestRunner 测试类名(图形格式,AWT版)、java junit.swingui.TestRunner测试类名(图形版,Swing版)。
 
  编译执行(即在命令行执行javac testQueue.javajavatestQueue), 你会发现屏幕上出现提示:
 
  .E 一个小点说明执行了一个测试用例,E表示其失败
 
  Time: 0.11 说明执行测试共花费了0.11
 
  There was 1 error: 说明存在一个错误
 
  
1) testEmpty(testQueue)java.lang.NoClassDefFoundError: Queue 
    
at testQueue.setUp(testQueue.java:13) 
    
at testQueue.main(testQueue.java:9) 
  
FAILURES!!! 
  
Tests run: 1, Failures: 0, Errors: 1 
  测试没有通过是肯定的,因为Queue类都还没有写呢?怎么可能通过测试,因此,我们就编写以下代码,以使测试通过:
 
public class Queue extends java.util.Vector 
{
public Queue()
{
super();
}
public boolean empty()
{
return super.isEmpty();
}

  将这个类编译后,再次执行测试程序,这时将出以下提示

  . 一个小点说明执行了一个测试用例,没有E表示其成功
 
  
Time: 0.11 
  
OK (1 test) 
  你还可以使用前面我们说到的另两个命令,使测试反馈以图形化的形式体现出来,例如,执行java junit.awtui.TestRunner testQueue 将出现: 




  第二次迭代
 
  接下来,我们修改测试程序,加入测试案例TC04TC05的考虑。
 
import junit.framework.*;
public class testQueue extends TestCase
{
protected Queue q1,q2;
public static void main (String[] args)
{
junit.textui.TestRunner.run (suite()); 

protected void setUp() { 
q1= new Queue();
q2= new Queue();
q2.inqueue("first"); /
对队列q2执行插入队列操作

q2.inqueue("second");
}
public static Test suite()
{
return new TestSuite(testQueue.class);
}
public void testEmpty()
{
assertTrue(q1.empty()); 
//
当队列新建时,应为空-TC01
}
public void testInqueue()
{
assertTrue(!(q2.empty())); 
//
执行了插入队列操作,队列就应不为空
-TC05
assertEquals(1,q2.search("second")); 
//search
方法用于确定元素在队列中的位置
 
//
后插入的数据元素,应在未尾
-TC04 
//
插入两个,第一个在位置0 第二在位置
1
}

  根据这个测试代码,我们需要在Queue类中添加上inqueue() search() 两个方法,如下所示:
 
public class Queue extends java.util.Vector 
{
public Queue()
{
super();
}
public boolean empty()
{
return super.isEmpty();
}
public synchronized void inqueue (Object x)
{
super.addElement(x);
}
public int search(Object x)
{
return super.indexOf(x);
}

  编译之后,再次执行java junit.awtui.TestRunnertestQueue 你将再次看到成功的绿色。 




  我们仔细看一下这一界面。
 
  1 最上面列出了测试代码的类名,右边有一个"Run" 按钮,当你需要再次运行这一测试代码时,只需单击这个按钮。另外,将"Reload classesevery run" 选项打上勾很有用,当你测试未通过(出现红色时), 你可以转身去修改代码,修改完后,只需再按"Run" 按钮就可以再次运行。
 
  2 中间区域是一个状态汇报区,红色表示未通过,统计了共运行了多少个测试(也就是在TestCase类中方法的数量)。
 
  3 如果测试时出现错误,例如,我们不小心将"assertTrue(!(q2.empty()));" 误写成为"assertTrue(q2.empty());" 就将造成测试失败:
 
  注:由于第一个测试还是通过的,因此你会看到绿色条一闪。这时,你将会发现JUnit会将错误列出来,并且对应的"Run"按钮也由灰变成了亮,这表示你可以转身修改,完成后单击这个"Run按钮"可以只做刚才失效的这个测试,这将节省大量的时间。
 
  同时,在最下面的窗体里,列出了失效的详细原因。
 


  后面的迭代 
  到这里,开发还没有完成,但这种思想却已经通过这样两个短小的实践传递出去了,后面的活大家可以动手试一下。
 
  另外值得一提的是,这里虽然洋洋洒洒一大篇,实际两次迭代花费了我不到15分钟就完成了。而且,当看到绿条时,心里十分舒畅。 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值