JUnit单元测试

 

         JUnit 单元测试
 
第一章JUnit的框架原理分析
1.              JUnit 主要用于单元测试,所谓的单元测试就是常常说的白盒测试。它是一个开源的由 JAVA 开发的一个用于测试的框架。
2.              下面我们主要是来看一下 JUnit 的设计原理
2.1. 首先我们来看一下 JUnit 的框架图。
      
            2.2. JUnit的几个基本的概念: TestCase TestSuite TestFixtrue
                TestCase: 代表一个测试用例,每一个 TestCase 实例都对应一个测试,                        
                这个测试通过这个 TestCase 实例的名字标志,以便在测试结果中指明哪
                个测试出现了问题 .TestCase 继承自 Assert, 因此可以实现各种断言。
                TestSuite :代表需要测试的一组测试用例,也就是测试用例的集合,
                TestFixtrue :代表一个测试环境。它用于组合一组测试用例,这组测试
                用例需要共同的测试运行环境。
 
 
            2.3. junit 的设计
            2.3.1. Test 接口 : 代表一个测试。它是框架的主接口有两个方法:
                    int countTestCases();//
返回所有测试用例的个数。
                    void run(TestResult result);//
运行一个测试,并且收集运行结果      
                    TestResult.
            2.3.2. TestCase : TestCase 实现了 Test 接口,是框架提供的供我们继承的类,我们的所有的测试方法都需要在 TestCase 的子类中定义,并且符合特定的设计协议。
                     一个 TestCase 实例代表一个具体的测试实例,对应一个对某一方法或概念的测试。每个 TestCase 实例都有一个名字。
                     一个 TestCase 类却定义了一个 TestFixture 。具体的说就是我们自己定义的 TestCase 子类中可以定义很多的 public 没有参数的 testxxx 方法。运行时,每个 testxxx 都在自己的 fixture 中运行。每个运行的 TestCase 都有一个名字,如果不指定,一般是 TestCase 中定义的 test 方法的名字。
            2.3.3. TestSuite : TestCase 一样 TestSuite 也实现了 Test 接口。一个 TestSuite 可以包含一系列的 TestCase 。把 testCase 组装入 TestSuite 有几种方式:
A ,通过将 TestCase Class 参数传入 TestSuite 的构造函数, TestSuite 会自动收集 TestCase 中所有的 public 的没有参数的 testxxx 方法加入 TestSuite 中。
B
,构造空的 TestSuite 后通过 void addTest(Test test) 方法添加测试。
C
:构造空的 TestSuite 后通过 void addTestSuite(Class testClass) 方法添加测试集。
            2.3.4. TestResult : 主要通过 runProtected 方法运行测试并收集所有运行结果
            2.3.5. TestRunner : 启动测试的主类,我们可以通过直接调用它运行测试用例, IDE 和其他一些工具一般也通过这个接口集成 JUnit.
            2.3.6.   Assert :   用于断言, TestCase 继承自该类,我们的测试方法通过这些断言判断程序功能是否通过测试
                  
 
           2.3.7. TestListener 接口 : 测试运行监听器,通过事件机制处理测试中产生的事件,主要用于测试结果的收集。
        以上是框架的核心接口和类的介绍,通过上面的介绍我们很容易看出来 Test
TestCase TestSuite 的设计采用了 Composite 模式。这样 JUnit 可以一次运行
一个测试用例,也可以一次运行多个测试用例, TestRunner 只关心 Test 接口,而
对运行的是单个的 TestCase 还是同时运行多个 TestCase 并不在意
         3. JUnit 同时使用了 Command 模式,对于典型的 Command 模式一般有 5
            种角色 :
            3.1 命令角色( Command ):声明执行操作的接口。有 java 接口或者抽象
                类来实现
            3.2. 具体命令角色( Concrete Command ):将一个接收者对象绑定于一
                 个动作;调用接收者相应的操作,以实现命令角色声明的执行操作的接
                 .
            3.3. 客户角色( Client ):创建一个具体命令对象(并可以设定它的接收者)。
            3.4. 请求者角色( Invoker ):调用命令对象执行这个请求 .
            3.5. 接收者角色( Receiver ):知道如何实施与执行一个请求相关的操作。
                任何类都可能作为一个接收者。
     Test 接口可以认为是命令模式中的命令角色 Command 接口, void run(TestRes
      ult result) 接口方法定义了需要执行的操作; TestCase 可以看作是具体命令角色,
      但又不全是,因为我们还需要自己通过继承 TestCase 类定义测试方法,这样的每一
      个测试方法都回被包装在一个 TestCase 实例中。 TestResult 可以看作请求者角色
       Invoker ),它会通过 protected void run(final TestCase test)  运行测试并
      收集结果。我们自己写的 Test 方法可以认为是接收者角色( Receiver ),因为我们
      的方法才具体执行这个命令。 TestRunner 就是客户角色( Client ),它通过 TestRe
      sult result= createTestResult() 构造 TestResult ,并通过 suite.run(result)
      行测试用例( suite 是一个 Test 接口的具体实例,可以是 TestCase 也可以是 Test
      Suite ,但客户端不关心它是什么,这就是组合模式的好处。同时, suite.run res
      ult )又调用 result.run test ),如果不仔细分析,就会被这种设计搞迷惑) .
 
                   
 
第二章JUnit的好处和单元测试的编写原则
         现在世面上有很多的测试工具,比如说NUNIT,PHPUNIT等。但是在JAVA的世界里面JUnit是最适合我们的单元测试工具。
    A: 可以使测试代码与产品代码分开
    B :针对某一个类的测试代码通过较少的改动便可以应用于另一个类的测试
    C :易于集成到测试人员的构建过程中, JUnit Ant 的结合可以实施增量开发
    D JUnit 是公开源代码的,可以进行二次开发
    E 可以方便地对 JUnit 进行扩展
 
编写原则 :
 A: 是简化测试的编写,这种简化包括测试框架的学习和实际测试单元的编写
 B: 是使测试单元保持持久性
 C: 是可以利用既有的测试来编写相关的测试
   
第三章JUnit的应用以及扩展
        下面是关于JUNIT的扩展方面的,主要说的是junit.extensions包
1.      ExceptionTestCase是TestCase的子类,用于对预见引发异常时的测试。生成该对象的时候要指明应该引发的异常的类型。runTest的时候会catch并吸收该异常。如果未发现该异常,则 测试失败
2.      ActiveTestSuite是TestSuite的子类,用独立的线程来运行每个测试实例。runTest(Test, TestResult)开启新线程来运行Test。run(TestResult)对所有的Test运行runTest(Test, TestResult),并等待所有线程结束。
3.      TestDecorator是Assert的子类,并实现了Test接口。它封装Test并把其Test.run(TestResult)作为一个basicRun(TestResult)。TestDecorator.run(TestResult)直接调用basicRun。子类可以重载run(TestResult),从而在原Test.run(TestResult)前后加入新的修饰代码
4.      RepeatedTest是TestDecorator的子类。RepeatedTest.run(TestResult)重复指定次数运行TestDecorator.run(TestResult)。因此countTestCases()也要在TestDecorator.countTestCases()基础上乘以重复次数。
5.      TestSetup是TestDecorator的子类。增加新的fixture。在basicRun(TestResult)前运行setUp(),在之后运行tearDown()。 BUG没有调用TestResult.startTest/endTest,即不产生开始/结束测试事件。

下面是个简单的例子:

Mytest.java类:

/*
 * �������� 2006-7-31
 *
 * TODO Ҫ��Ĵ���ɵ��ļ���ģ�壬��ת��
 * ���� �� ��ѡ�� �� Java �� ������ʽ �� ����ģ��
 */

/**
 * @author mahb
 *
 * TODO Ҫ��Ĵ���ɵ�����ע�͵�ģ�壬��ת��
 * ���� �� ��ѡ�� �� Java �� ������ʽ �� ����ģ��
 */
public class Mytest {
 
 String name;
 String birthday;
 int age;
 

 /**
  * @return ���� age��
  */
 public int getAge() {
  return age;
 }
 /**
  * @param age Ҫ���õ� age��
  */
 public void setAge(int age) {
  this.age = age;
 }
 /**
  * @return ���� birthday��
  */
 public String getBirthday() {
  return birthday;
 }
 /**
  * @param birthday Ҫ���õ� birthday��
  */
 public void setBirthday(String birthday) {
  this.birthday = birthday;
 }
 /**
  * @return ���� name��
  */
 public String getName() {
  return name;
 }
 /**
  * @param name Ҫ���õ� name��
  */
 public void setName(String name) {
  this.name = name;
 }
}
 

MytestTest .java类

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/*
 * �������� 2006-7-31
 *
 * TODO Ҫ��Ĵ���ɵ��ļ���ģ�壬��ת��
 * ���� �� ��ѡ�� �� Java �� ������ʽ �� ����ģ��
 */

/**
 * @author mahb
 *
 �� ����ģ��
 */
public class MytestTest extends TestCase {

 /*
  * @see TestCase#setUp()
  */
 protected void setUp() throws Exception {
  super.setUp();
 }

 /*
  * @see TestCase#tearDown()
  */
 protected void tearDown() throws Exception {
  super.tearDown();
 }

 /**
  * Constructor for MytestTest.
  * @param arg0
  */
 public MytestTest(String arg0) {
  super(arg0);
 }
 
 public static Test suite(){
     TestSuite ts = new TestSuite(); 
     //TestSuite ts = new TestSuite(MytestTest.class);
     ts.addTest(new MytestTest("testgetName"));
     return ts;
 }
 
 public void testgetName(){
     Mytest mt = new Mytest();
     mt.setName("mahb");
    //    assertEquals("gaofei",mt.getName()); 
        System.out.println("12345455---" + mt.getName());
      
 }
 public void testgetBirthday(){
     Mytest mt = new Mytest();
     mt.setBirthday("1983.05.26");
       // assertNull(mt.getBirthday());
        assertNotNull(mt.getBirthday());
        assertTrue(mt.getBirthday().equals("1982.1.20"));
        System.out.println("-------"+mt.getBirthday());
 }

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值