2007-09-10

测试驱动开发With JUnit(二)

关键字: java 测试 junit
第二章:JUnit测试套件:
       在第一节中简单的介绍了JUnit的使用,但是每次运行测试类时,该测试类的所有方法全部都被测试一遍,如果想单独测试某个方法还是比较麻烦的。但是可以利用测试套件来解决这个问题。
       下面我们先更改CalculateUtilTest向里面增加一个构造方法
 
  1. import junit.framework.TestCase;   
  2. public class CalculateUtilTest extends TestCase   
  3. {   
  4.     
  5.     public CalculateUtilTest(String name)    //1行   
  6.     {   
  7.         super(name);   
  8.     }   
  9.     
  10.  ……其余方法省略   
  11. }  

       代码解释:
       1行:自定义构造方法,里面有一个String参数,在该方法中调用父类的构造方
                 法。
       构造一个类来操作测试套件:
  1. import junit.framework.*;   
  2. public class MainTest   
  3. {   
  4.     public static Test suite()  //1行   
  5.     {   
  6.         TestSuite suite = new TestSuite();  //2行   
  7.      
  8.         //添加测试testDivision方法   
  9.         suite.addTest(new CalculateUtilTest("testDivision"));  //3行   
  10.      
  11.         //添加测试testCreate方法   
  12.         suite.addTest(new CalculateUtilTest("testCreate"));   
  13.         return suite;   
  14.     }   
  15.     
  16.     public static void main(String[] args)   
  17.     {   
  18.         //执行测试   
  19.         junit.textui.TestRunner.run(suite());   //4行   
  20.     }   
  21. }   
       代码解释:
       1行:静态方法,返回Test类对象。该方法主要是构造TestSuite类对象,然后向
                其中加入你想要测试的方法。
       2行:构造TestSuite类对象
       3行:向TestSuite对象中添加一个要测试的方法。
                 new CalculateUtilTest("testDivision")表示测试CalculateUtilTest类的
                 testDivision方法。
       4行:运行该测试套件
       上面的方法可以非常方便地添加自己所需要的方法,如果是用该方法,就要在编写测试方法时将其加入测试套件中。如果你觉得很麻烦,那么就使用下列一行代码一次测试一个类吧。
  1. public static void main(String[] args)   
  2. {   
  3.     junit.swingui.TestRunner.run(CalculateUtilTest.class);   
  4. }  

        或者在suite方法中添加所要测试的类也可以
  1. public static Test suite()   
  2. {   
  3.     TestSuite suite = new TestSuite();   
  4.     suite.addTestSuite(CalculateUtil.class);   
  5.     return suite;   
  6. }  
       尽管上面的测试套件提供了你所需要的各种粒度测试方法(按照方法名,测试整个类),但是有个问题是,当我们面临一大堆测试代码时,很容易忘记将你的测试类加入到一个测试套件中去。一个好的解决方法是让java程序扫描你的classpath中的全部类,搜集所需要的测试类然后逐一执行。这样做的好处就是不会有测试被遗漏,但缺点是某些测试,你并不希望每次都运行它们。具体做法如下:先编写收集测试类的功能,并将全部测试类装入测试套件。代码如下
  1. import java.lang.reflect.Modifier;   
  2. import java.util.*;   
  3. import junit.runner.*;   
  4. import junit.framework.*;   
  5. public class SuiteBuilder   
  6. {   
  7.     //将所有的测试类都加入TestSuite中   
  8.     public  Test suite()   
  9.     {   
  10.         TestSuite suite=new TestSuite();   
  11.      
  12.         List list=getTestClassNames();   
  13.         for(int i=0;i
  14.         {   
  15.             suite.addTestSuite(createClass(list.get(i).toString()));   
  16.         }   
  17.         return suite;   
  18.     }   
  19.     
  20.     //获取全部测试类的类名   
  21.     public List   getTestClassNames()   
  22.     {   
  23.         TestCollector collector = new ClassPathTestCollector()   
  24.         {   
  25.             public boolean isTestClass(String classFileName)   
  26.             {   
  27.                 if (!super.isTestClass(classFileName))   
  28.                      return false;   
  29.                 String className = classNameFromFile(classFileName);   
  30.                 Class clazz = createClass(className);   
  31.                 return TestCase.class.isAssignableFrom(clazz) && isConcrete(clazz);   
  32.             }   
  33.         };   
  34.         return Collections.list(collector.collectTests());   
  35.     }   
  36.     //判断该类是否是接口或抽象类   
  37.     private boolean isConcrete(Class clazz)   
  38.     {   
  39.         if (clazz.isInterface())   
  40.             return false;   
  41.         int modifiers = clazz.getModifiers();   
  42.        return !Modifier.isAbstract(modifiers);   
  43.      }   
  44.      //加载该类   
  45.     private Class createClass(String name)   
  46.     {   
  47.         try  
  48.         {   
  49.             return Class.forName(name);   
  50.         }   
  51.         catch (ClassNotFoundException e)   
  52.         {   
  53.             return null;   
  54.         }   
  55.      }   
  56.     //判断该类是否是测试类:标准如下   
  57.     //1:类文件以.class结束   
  58.     //2:类名不能有$,防止内部类   
  59.     //3:类名必须以Test单词结尾   
  60.     protected boolean isTestClass(String classFileName)   
  61.     {   
  62.         return classFileName.endsWith(".class") && classFileName.indexOf('$') < 0 &&     
  63.                                   classFileName.indexOf("Test") > 0;   
  64.     }   
  65. }   
       注:注释都比较详细,在这里就不多解释了。
       然后编写测试套件类:
  1. package com;   
  2. public class MainTest   
  3. {   
  4.     public static void main(String[] args)   
  5.     {   
  6.         junit.textui.TestRunner.run(new SuiteBuilder().suite());   
  7.     }   
  8. }  

       运行该测试套件,你会发现在你的classpath下的所有测试类都会被执行。只不过是文本形式显示结果。
评论
发表评论

您还没有登录,请登录后发表评论

leon0122
搜索本博客
最近访客
最近加入圈子
最新评论
评论排行榜