西西軟件下載最安全的下載網(wǎng)站、值得信賴(lài)的軟件下載站!

首頁(yè)編程開(kāi)發(fā)其它知識(shí) → java測(cè)試工具junit開(kāi)源框架錯(cuò)誤調(diào)試實(shí)例

java測(cè)試工具junit開(kāi)源框架錯(cuò)誤調(diào)試實(shí)例

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:西西整理時(shí)間:2013/1/20 0:31:38字體大。A-A+

作者:西西點(diǎn)擊:0次評(píng)論:0次標(biāo)簽: junit

因?yàn)楣ぷ骱蛯W(xué)習(xí)的需要,在代碼中查錯(cuò)的時(shí)候,第一步就是想知道這個(gè)錯(cuò)誤具體發(fā)生在一個(gè)位置,進(jìn)行一個(gè)準(zhǔn)確的定位。而這個(gè)定位的工作交給誰(shuí)來(lái)做了呢?不難猜出也就是這篇博客的主題---Junit。junit是一個(gè)開(kāi)源的框架,也是java這一塊的測(cè)試工具之一。想了解詳細(xì)請(qǐng)上官網(wǎng),下面用代碼來(lái)跟大家解釋。

準(zhǔn)備要測(cè)試的方法,放進(jìn)一個(gè)類(lèi)中方便于測(cè)試。

package com.junit3_8;

/**
 * junt3.8單元測(cè)試
 * 
 * @author CHH
 * @since 2013-01-19
 * 
 */
public class Calculator {

    // 加
    public int add(int a, int b) {
        
        int sum=0;
        for(int i=0;i<100;i++){
            sum +=i;
            
        }
        System.out.println("加=="+sum);
        return a+b;
    }

    // 減
    public int subtract(int a, int b) {
        int sum=0;
        for(int i=0;i<100;i++){
            sum +=i;
            
        }
        System.out.println("減=="+sum);
        return a - b;
    }

    // 乘
    public int multiply(int a, int b) {
        int sum=0;
        for(int i=0;i<100;i++){
            sum +=i;
            
        }
        System.out.println("乘==="+sum);
        return a * b;
    }

    // 除
    public int divide(int a, int b) throws Exception {
        int sum=0;
        for(int i=0;i<100;i++){
            sum +=i;
            
        }
        System.out.println("除==="+sum);
        
        if (0 == b) {
            throw new Exception("除數(shù)不能為0");
        }
        return a / b;
    }
}

Junit3.8測(cè)試類(lèi)

package com.junit3_8;

import junit.framework.Assert;
import junit.framework.TestCase;
/**
 * 
 * @author CHH
 * @since 2013-01-19
 */
public class CalculatorTest extends TestCase {
    
    Calculator cal;
    
    //在“每個(gè)”測(cè)試方法執(zhí)行之前被調(diào)用  
    public void setUp()  
    {  
        //這段代碼在這寫(xiě)比較方便,只寫(xiě)一次就夠,  
        //不用在每個(gè)方法里寫(xiě),因?yàn)檫@個(gè)方法每次都被調(diào)用,生成不同的對(duì)象,供測(cè)試方法使用  
        cal = new Calculator();  
    }
    
    //在“每個(gè)”測(cè)試方法執(zhí)行之后被調(diào)用  
    public void tearDown()  
    {  
         
    }
    
    //測(cè)試方法:方法名要以test為開(kāi)頭,無(wú)參數(shù),無(wú)返回類(lèi)型  
    public void testAdd()  
    {  
        //Calculator cal = new Calculator();  
        int result = cal.add(1, 2); 
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的  
        
        Assert.assertEquals(3, result); 
        
        //Assert.fail();
          
    } 
    
    public void testSubtract()  
    {  
        //Calculator cal = new Calculator();  
        int result = cal.subtract(1, 2);  
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的  
        Assert.assertEquals(-1, result);  
          
    }
    
    public void testMultiply()  
    {  
        //Calculator cal = new Calculator();  
        int result = cal.multiply(1, 2);  
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的  
        Assert.assertEquals(2, result);  
          
    }
    
    public void testDivide()  
    {  
        int result = 0;  
        //Calculator cal = new Calculator();  
        try   
        {  
            result = cal.divide(4, 2);  
              
        }  
        catch(Exception e)  
        {  
            e.printStackTrace();  
            //讓測(cè)試失敗  
            Assert.fail();  
        }  
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的  
        Assert.assertEquals(2, result);  
          
    }
    
    //除數(shù)為0的情況  
    public void testDivideByZero()  
    {  
        Throwable th = null ;  
          
        //Calculator cal = new Calculator();  
        try   
        {  
            cal.divide(1, 0);  
            Assert.fail();  
        }  
        catch(Exception e)  
        {  
            th = e ;  
            //e.printStackTrace();  
        }  
          
        //th 不為空 null  
        Assert.assertNotNull(th);  
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的  
        Assert.assertEquals(Exception.class, th.getClass());  
        Assert.assertEquals("除數(shù)不能為0", th.getMessage());  
          
    }
    
    //加了這個(gè)main方法,可以直接以 Java Application 方式運(yùn)行 ,也可以以 JUnit Test 運(yùn)行  
    public static void main(String[] args)  
    {  
        //命令行形式打印  
        junit.textui.TestRunner.run(CalculatorTest.class);  
          
        //awt 界面方式顯示  
        //junit.awtui.TestRunner.run(CalculatorTest.class);  
          
        //swing 界面方式顯示  
        //junit.swingui.TestRunner.run(CalculatorTest.class);  
    }

}

從上面的代碼中可以看出Junit測(cè)試類(lèi)是通過(guò)繼承一個(gè)TestCase類(lèi)來(lái)實(shí)現(xiàn)方法的測(cè)試,而這就是Junit4.0以前的測(cè)試方式,而在4.0之后他們的實(shí)現(xiàn)方式又有了稍微的變化。

Junit4.0之后不再是通過(guò)繼承TestCase的方式來(lái)實(shí)現(xiàn)方法的實(shí)測(cè),而是采用注解的方式進(jìn)行的。根據(jù)Java 5.0中的新特征(注解,靜態(tài)導(dǎo)入等),Junit開(kāi)發(fā)團(tuán)隊(duì)也隨之靠攏,采用注解的方式來(lái)進(jìn)行方法的測(cè)試。這樣下來(lái)相比而言JUnit 4更簡(jiǎn)單、更豐富和更易于使用。

Junit4.0測(cè)試類(lèi)
package com.junit4_0;

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
/**
* Junit4.0
* @author CHH
* @since 2013-01-19 晚上10:12
*
*/
public class CalculatorTest {

    private static Calculator calculator = new Calculator();

    //每個(gè)方法測(cè)試前調(diào)用
    @Before
    public void clearCalculator() {
        calculator.clear();
    }
   
    //每個(gè)方法測(cè)試完以后調(diào)用
    @After
    public void tearDown() 
    { 
        
    }
   
    //@Test:測(cè)試方法,表明這是一個(gè)測(cè)試方法。在Junit中將會(huì)自動(dòng)被執(zhí)行。
    @Test
    public void add() {
        calculator.add(1);
        calculator.add(1);
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的 
        assertEquals(calculator.getResult(), 2);
    }

    @Test
    public void subtract() {
        calculator.add(10);
        calculator.substract(2);
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的 
        assertEquals(calculator.getResult(), 8);
    }

    //給測(cè)試函數(shù)設(shè)定一個(gè)執(zhí)行時(shí)間,超過(guò)了這個(gè)時(shí)間(400毫秒),它們就會(huì)被系統(tǒng)強(qiáng)行終止
    @Test(timeout=400)
    public void divide() {
        calculator.add(8);
        calculator.divide(2);
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的 
        assert calculator.getResult() == 5;
    }

    //使用注釋來(lái)聲明該異常是預(yù)期的,異常測(cè)試是Junit4中的最大改進(jìn)
    @Test(expected = ArithmeticException.class)
    public void divideByZero() {
        calculator.divide(0);
    }

    //@Ignore:忽略的測(cè)試方法,標(biāo)注的含義就是“某些方法尚未完成,暫不參與此次測(cè)試”
    @Ignore("not ready yet")
    @Test
    public void multiply() {
        calculator.add(10);
        calculator.multiply(10);
        //第一個(gè)參數(shù)是預(yù)期的,第二個(gè)參數(shù)是真實(shí)的 
        assertEquals(calculator.getResult(), 100);
    }

}

Junit4出了采用的注解的方式來(lái)進(jìn)行測(cè)試方法之外,還增加了一些新的元素。

     A、JUnit4添加了兩個(gè)比較數(shù)組的assert() 方法:

  public static void assertEquals(Object[] expected, Object[] actual)

  public static void assertEquals(String message, Object[] expected, Object[] actual)

Junit4常用注解:

    @Test  測(cè)試方法,表明這是一個(gè)測(cè)試方法。在Junit中將會(huì)自動(dòng)被執(zhí)行。

    @Test(timeOut=400)  給測(cè)試函數(shù)設(shè)定一個(gè)執(zhí)行時(shí)間,超過(guò)了這個(gè)時(shí)間(400毫秒),它們就會(huì)被系統(tǒng)強(qiáng)行終止

    @Test(expected = ArithmeticException.class)  使用注釋來(lái)聲明該異常是預(yù)期的,異常測(cè)試是Junit4中的最大改進(jìn)

    @Ignore("not ready yet")    忽略的測(cè)試方法,標(biāo)注的含義就是“某些方法尚未完成,暫不參與此次測(cè)試”

    @Before   每個(gè)方法測(cè)試前調(diào)用

    @After   每個(gè)方法測(cè)試完以后調(diào)用

    @BeforeClass   每個(gè)類(lèi)運(yùn)行前調(diào)用,并且只調(diào)用一次

    @AfterClass  每個(gè)類(lèi)運(yùn)行后調(diào)用,并且只調(diào)用一次

表格.@BeforeClass/@AfterClass比較于@Before/@After。

@BeforeClass和@AfterClass@Before和@After
在每個(gè)類(lèi)中只有一個(gè)方法能被注解。多個(gè)方法能被注解,但其執(zhí)行的順序未特別指定,且不運(yùn)行重載方法。
方法名是不相關(guān)的方法名是不相關(guān)的
每個(gè)類(lèi)運(yùn)行一次在每個(gè)測(cè)試方法運(yùn)行前或運(yùn)行后運(yùn)行
在當(dāng)前類(lèi)的@BeforeClass方法運(yùn)行前先運(yùn)行超類(lèi)的@BeforeClass方法。在超類(lèi)中聲明的@AfterClass方法將在所有當(dāng)前類(lèi)的該方法運(yùn)行后才運(yùn)行。超類(lèi)中的@Before在所有子類(lèi)的該方法運(yùn)行前運(yùn)行。在超類(lèi)中的@After在在所有子類(lèi)的該方法運(yùn)行后才運(yùn)行。
必須是公共和非靜態(tài)的。必須是公共和非靜態(tài)的。
即使一個(gè)@BeforeClass方法拋出一個(gè)異常,所有的@AfterClass方法也保證被運(yùn)行。即使一個(gè)@Before或者@Test方法拋出一個(gè)異常,所有的@After方法也保證被運(yùn)行。

總結(jié):這兩個(gè)版本最大的區(qū)別在JUnit3.x中測(cè)試必須繼承 TestCase,并且每個(gè)方法名必須以test開(kāi)頭。比如:testMethod1()而在JUnit4.x中不必繼承TestCase,采用了注解的 方式。只要在測(cè)試的方法上加上注解@Test即可,從而不必再遵循以前的一些顯式約定和反射定位測(cè)試;在JUnit4.x中如果繼承了TestCase, 注解就不起作用了。

并且有很重要的一點(diǎn)就是在JUnit4.x中繼承了TestCase后,在OutLine視圖中測(cè)試單個(gè)方法時(shí),結(jié)果整個(gè)類(lèi)都run 了。還有一點(diǎn)就是,在3.x中需要實(shí)現(xiàn)setUp和tearDown方法,而在4.x中無(wú)需這樣,可以自定義需要在測(cè)試前和測(cè)試后的方法,在方法前加上 @before,@after就可以了。所以在JUnit4.x不必繼承TestCase用注解即可對(duì)單個(gè)方法進(jìn)行測(cè)試

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱(chēng):
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)
    推薦文章

    沒(méi)有數(shù)據(jù)