Junit测试代码基本骨架和一些基本总结

本来在做watir恰逢遇到项目,被打断了,目前需要做单元测试,于是给我了机会一亲Junit芳泽。花了些日子读资料在eclipse上从最简单的一行代码的测试到对一个类写针对性的测试,到现在开始考虑一些结构的问题,也收获颇丰。

前后对比一下,阅读了一些书籍和材料总结到以下几点:

1. Junit写出来测试代码的基本骨架的样式大概就是下面的:(// 和/**开头那些都是为了方便理解而加的注释)

基本顺序就是

(1) import junit.framework.* 下面所有的类

(2) extends 用自己的测试类继承TestCase

(3) 初始化和释放资源的方法 setUp()和tearDown()

(4) 写一个构造函数用super 调用 父类构造函数

(5) test开头的测试方法。

(6) 定义testsuite,指定testsuite要执行的测试方法

(7)如果要在命令行下执行测试,需要用main函数指定待运行testsuite和一系列定义,以及运行方法和运行对象等等。

 

本文出自jaunty软件测试博客,转载请保留出处及链接:http://jaunty.me/blog

下面就是按照这个骨架的基本代码模版:

package Skeleton;
import junit.framework.*;
 //change all occurrences of “skeleton” below
 // appropriate
public class TestSkeleton extends TestCase {
 /**
  * Pre-method test setup()
  */
 public void setUp(){
 }
 /**
  * Pre-Method tear down()
  */
 public void tearDown(){
  
 }
 /**
  * Add test here,
  * public void testxxx(){
  * }
  */
 public TestSkeleton(String name){
  super(name);
  
 }
 /**
  * Default suite method
  */
 
 public static Test suite(){
  return new TestSuite(TestSkeleton.class);
  
 }
 /**
  * main method only be invoked from command line.
  *
  */
 
 public static void main (String[] args){
  TestSuite suite = new TestSuite();
  if (args.length!=0){
   //Run specified test
   for (int i=0;i<args.length;i++){
    suite.addTest(new TestSkeleton(args[i]));    
   }
  }
  else {
   //discover all of them or use user defined suite
   suite.addTest(TestSkeleton.suite());
  }
  junit.textui.TestRunner.run(suite);
 }

}

上面这个模版用起来固然好,不过有个问题,就是复用性。假设我们都需要在setUp()下面作数据库联接。然后我们100个测试类都用这个模版。然后如果我们数据库的联接某天变了,那你就的在100个测试类里逐个的改去吧。

2. 可以写一个类专门来集合要测试的方法或者suite,然后可以指定来运行。

看下面一个小的范例:

import Example.ExampleHelloTest; //因为ExampleHelloTest在另外一个包里所以需要import进来
import junit.framework.*;
import pragmaticUnitTest.TestLargest;//因为TestLargest在另外一个包里所以需要import进来

public class TestSuiteComposite extends TestCase{
 public TestSuiteComposite (String  method){
 super(method);
 }

/**

*define composited testsuite

*/ 

static public Test suite(){
  TestSuite suite = new TestSuite();

// add all the test methods from ExampleHelloTest class.

  suite.addTestSuite(ExampleHelloTest.class);
//  add test suite from TestLargest class. 

suite.addTest(TestLargest.suite());
  return suite;
  
 }
}

基本结构就是ExampleHelloTest class定义了一系列的测试方法但是没有定义test suite.这里就把这个class里的所有的测试方法加进来。然后又把TestLargest class 里定义的suite加进来。实际上在TestLargest class里定义了10个测试方法。但是TestLargest class的suite只是指定了其中的2个来运行。因此在这个composite的class里我们运行顺序是先把ExampleHelloTest定义的所有测试方法执行然后再执行TestLargest class 里suite里限定的2个测试方法。

我个人感觉,这样把测试的执行操控放到一个class里来作是很方便也很容易修改的,毕竟只有一个接口。

因此对于第一大点提到的那个复用性的缺点。我个人感觉 其实我们可以把那些实际的一些需要复用又容易引起修改的,例如第一大点里数据库连接修改的例子,我们可以放在这个唯一入口的测试类的suite setUp()和tearDown()方法里。这样只需要改一次。这点是我自己设想的,还没有实践过。

本文出自jaunty软件测试博客,转载请保留出处及链接:http://jaunty.me/blog

3. 这点是针对第2点提出来的。就是可以考虑不要直接用实际的测试类直接继承TestCase.可以一开始自己制定一个空的class继承TestCase。然后所有的测试都去继承这个自定义的基类。这样的好处也是一些公用的方法和处理的时候很容易就控制和修改了。

4. 运行单元测试的时候可以选择每次都运行所有的测试,一旦某个地方改了就把所有的测试都运行一遍以保证不会造成已经走了很远了发现出错,难究根源。但是对于一些非常耗时的test,可以选择隔断时间运行一次。

最后发发牢骚,以前也不知道谁说的java跟C#一样,可能是我coding太菜了,体会不到真谛,我感觉他们仅仅是一些所谓的特性或者原理一样而已,那些需要增加coding功底的细节,那些一句话就能考量出你深入这个语言多深的细节都还是很不一样的。至少我感觉跟我以前做过的C#的程序的一些编写的基本的细节还是不一样的。只不过说语言来来回回就那些事。主旨和思想来回就是那些但是精通的人却很少,毕竟想professional还是需要日月积累的。

Tags: , ,

Leave a Comment