<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    常用鏈接

    統(tǒng)計(jì)

    最新評(píng)論

    單元測(cè)試(Unit Test)(轉(zhuǎn))

    B.1 單元測(cè)試(Unit Test)

    一個(gè)單元(Unit)是指一個(gè)可獨(dú)立進(jìn)行的工作,獨(dú)立進(jìn)行指的是這個(gè)工作不受前一次或接下來(lái)的工作的結(jié)果影響。簡(jiǎn)單地說(shuō),就是不與程序運(yùn)行時(shí)的上下文(Context)發(fā)生關(guān)系。

    如果是在Java程序中,具體來(lái)說(shuō)一個(gè)單元可以是指一個(gè)方法(Method)。這個(gè)方法不依賴于前一次運(yùn)行的結(jié)果,也不牽涉到后一次的運(yùn)行結(jié)果。

    舉例來(lái)說(shuō),下面這個(gè)程序的gcd()方法可視為一個(gè)單元:

    Ü MathTool.java

    package onlyfun.caterpillar;

    public class MathTool {

        public static int gcd(int num1, int num2) {

            int r = 0;

            while(num2 != 0) {

                r = num1 % num2;

                num1 = num2;

                num2 = r;

            }

            return num1;

        }

    }

    下面的gcd()方法不可視為一個(gè)單元,要完成gcd的計(jì)算,必須調(diào)用setNum1()setNum2()gcd() 3個(gè)方法。

    Ü MathFoo.java

    package onlyfun.caterpillar;

    public class MathFoo {

        private static int num1;

        private static int num2;

        public static void setNum1(int n) {

            num1 = n;

        }

        public static void setNum2(int n) {

            num2 = n;

        }

        public static int gcd() {

            int r = 0;

            while(num2 != 0) {

                r = num1 % num2;

                num1 = num2;

                num2 = r;

            }

            return num1;

        }

    }

    然而要完全使用一個(gè)方法來(lái)完成一個(gè)單元操作在實(shí)現(xiàn)上是有困難的,所以單元也可廣義解釋為數(shù)個(gè)方法的集合。這數(shù)個(gè)方法組合為一個(gè)單元操作,目的是完成一個(gè)任務(wù)。

    不過(guò)設(shè)計(jì)時(shí)仍優(yōu)先考慮將一個(gè)公開的方法設(shè)計(jì)為單元,輔助的方法則使用設(shè)定為私用,盡量不用數(shù)個(gè)公開的方法來(lái)完成一件工作,以保持接口簡(jiǎn)潔與單元邊界清晰。將工作以一個(gè)單元進(jìn)行設(shè)計(jì),這使得單元可以重用,并且也使得單元可以進(jìn)行測(cè)試,進(jìn)而增加類的可重用性。

    單元測(cè)試指的是對(duì)每一個(gè)工作單元進(jìn)行測(cè)試,了解其運(yùn)行結(jié)果是否符合我們的要求。例如當(dāng)編寫完MathTool類之后,也許會(huì)這么寫一個(gè)小小的測(cè)試程序:

    Ü MathToolTest.java

    package test.onlyfun.caterpillar;

    import onlyfun.caterpillar.MathTool;

    public class MathToolTest {

        public static void main(String[] args) {

            if(MathTool.gcd(10, 5) == 5) {

                System.out.println("GCD Test OK!");

            }

            else {

                System.out.println("GCD Test Fail!");

            }

        }

    }

    在文字模式下使用文字信息顯示測(cè)試結(jié)果,這個(gè)動(dòng)作是開發(fā)人員經(jīng)常作的事情,然而您必須一行一行看著測(cè)試程序的輸出結(jié)果,以了解測(cè)試是否成功。另一方面,測(cè)試程序本身也是一個(gè)程序,在更復(fù)雜的測(cè)試中,也許會(huì)遇到測(cè)試程序本身出錯(cuò),而導(dǎo)致無(wú)法驗(yàn)證結(jié)果的情況。

    JUnit是一個(gè)測(cè)試框架,通過(guò)它所提供的工具,可以減少編寫錯(cuò)誤的測(cè)試程序的機(jī)會(huì)。另一方面,可以有更好的方法來(lái)檢驗(yàn)測(cè)試結(jié)果,而不是看著一長(zhǎng)串輸出的文字來(lái)檢驗(yàn)測(cè)試是否成功。JUnit測(cè)試框架讓測(cè)試的進(jìn)行更有效率且更具可靠性。

    B.2 JUnit設(shè)置

    JUnit最初是由Erich GammaKent Beck編寫,為單元測(cè)試的支持框架,用來(lái)編寫與執(zhí)行重復(fù)性的測(cè)試。它包括以下特性:

    Ü   對(duì)預(yù)期結(jié)果作判斷

    Ü   提供測(cè)試裝備的生成與銷毀

    Ü   易于組織與執(zhí)行測(cè)試

    Ü   圖形與文字接口的測(cè)試器

    要設(shè)定JUnit,可先到 JUnit官方網(wǎng)站(http://junit.org/)下載JUnitzip文件,下載后解開壓縮文件,其中會(huì)含有junit.jar文件,將這個(gè)文件復(fù)制到所要的數(shù)據(jù)夾中,然后設(shè)定Classpath指向junit.jar。例如:

    set classpath=%classpath%;YOUR_JUNIT_DIR\junit.jar

    如果是Windows 2000/XP,可以在環(huán)境變量中設(shè)定Classpath變量(可參考附錄A中的Classpath設(shè)置介紹)

    B.3 第一個(gè)JUnit測(cè)試

    要對(duì)程序進(jìn)行測(cè)試,首先要設(shè)計(jì)測(cè)試案例(Test Case)。一個(gè)測(cè)試案例是對(duì)程序給予假定條件,然后運(yùn)行程序并看看在給定的條件下,程序的運(yùn)行結(jié)果是否符合要求。

    JUnit下,可以繼承TestCase來(lái)編寫測(cè)試案例,并定義測(cè)試方法,每一個(gè)測(cè)試方法是以testXXX()來(lái)命名。一個(gè)例子如下所示:

     

    Ü MathToolUnitTest.java

    package test.onlyfun.caterpillar;

     

    import onlyfun.caterpillar.MathTool;

    import junit.framework.TestCase;

     

    public class MathToolUnitTest extends TestCase {

        public void testGcd() {

            assertEquals(5, MathTool.gcd(10, 5));

        }

       

        public static void main(String[] args) {

            junit.textui.TestRunner.run(MathToolUnitTest.class);

        }

    }

    assertEquals()方法用來(lái)斷定您的預(yù)期值與單元方法實(shí)際的返回結(jié)果是否相同,如果預(yù)期值與返回的結(jié)果不同則丟出異常,TestRunner會(huì)捕捉異常,并提取其中的相關(guān)信息以報(bào)告測(cè)試結(jié)果。這里使用的是文字模式的TestRunner

    接下來(lái)根據(jù)測(cè)試案例編寫實(shí)際的程序,首先試著讓測(cè)試案例能通過(guò)編譯:

    package onlyfun.caterpillar;
     
    public class MathTool {
        public static int gcd(int num1, int num2) { 
            return 0;
        }
    }

    編譯完MathTool.java并用javac來(lái)編譯它。在編譯完成之后,接著運(yùn)行測(cè)試案例,會(huì)得到以下的結(jié)果:

    .F
    Time: 0
    There was 1 failure:
    1) testGcd(test.onlyfun.caterpillar.MathToolUnitTest)junit.framework.AssertionFa
    iledError: expected:<5> but was:<0>
    ...
    FAILURES!!!
    Tests run: 1,  Failures: 1,  Errors: 0

    由于MathTool中并沒(méi)有編寫什么實(shí)際的邏輯,所以測(cè)試失敗。在測(cè)試驅(qū)動(dòng)中,測(cè)試案例所報(bào)告的結(jié)果通常是以測(cè)試失敗作為開始,您的挑戰(zhàn)就是要一步步消除這些失敗的信息。接下來(lái)根據(jù)測(cè)試案例,完成所設(shè)計(jì)的程序:

    Ü MathTool.java

    package onlyfun.caterpillar;

     

    public class MathTool {

        public static int gcd(int num1, int num2) {

            int r = 0;

            while(num2 != 0) {

                r = num1 % num2;

                num1 = num2;

                num2 = r;

            }

            return num1;

        }

    }

    再次運(yùn)行測(cè)試案例,會(huì)得到以下的結(jié)果,通過(guò)最后的OK信息,知道測(cè)試已經(jīng)成功:

    .Time: 0
     
    OK (1 test)

    不一定要在main()中指定TestRunner,而可以直接啟動(dòng)一個(gè)TestRunner,并指定測(cè)試案例類(繼承TestCase的類)。例如啟動(dòng)一個(gè)Swing窗口的測(cè)試結(jié)果畫面:

    java junit.swingui.TestRunner test.onlyfun.caterpillar.MathToolUnitTest

    執(zhí)行的結(jié)果畫面如圖B-1所示。

    Swing窗口的測(cè)試結(jié)果顯示中,如果中間的橫棒是顯示綠色,表示所有的測(cè)試都已經(jīng)成功,如果中間的橫棒顯示紅色,表示測(cè)試失敗。JUnit的名言Keep the bar green to keep the code clean,意思是保持綠色橫棒以保證測(cè)試成功。

    也可以指定文字模式的測(cè)試結(jié)果。例如:

    java junit.textui.TestRunner test.onlyfun.caterpillar.MathToolUnitTest

    B-1  JUnitSwing窗口測(cè)試結(jié)果

    B.4 自動(dòng)構(gòu)建與測(cè)試

    Ant可以進(jìn)行自動(dòng)化構(gòu)建,而JUnit可以進(jìn)行自動(dòng)化測(cè)試,Ant可以與JUnit結(jié)合,使得自動(dòng)化的構(gòu)建與測(cè)試變得可行。

    如果要讓Ant能支持JUnit,建議直接將JUnitjunit.jar放置在Antlib目錄,并記得改變Classpath中原先有關(guān)junit.jar的設(shè)定。例如將Classpath重新指向%ANT_HOME%\lib\junit.jar(假設(shè)已經(jīng)如附錄A中設(shè)置了ant_home的環(huán)境變量)。雖然也有其他的方式可以設(shè)定,但這是最快也是最簡(jiǎn)單的方法。

    Ant使用<junit>標(biāo)簽來(lái)設(shè)定JUnit測(cè)試,下面是一個(gè)簡(jiǎn)單的例子:

     

    <?xml version="1.0"?>

    <project name="autoBuildTest" default="test">

        <target name="setProperties">

            <property name="src.dir" value="src"/>

            <property name="classes.dir" value="classes"/>

        </target>

     

        <target name="prepareDir" depends="setProperties">

            <delete dir="${classes.dir}"/>

            <mkdir dir="${classes.dir}"/>

        </target>

     

        <target name="compile" depends="prepareDir">

            <javac srcdir="${src.dir}" destdir="${classes.dir}"/>

        </target>

     

        <target name="test" depends="compile">

            <junit printsummary="yes">

                <test

                   name="test.onlyfun.caterpillar.MathToolUnitTest"/>

                <classpath>

                    <pathelement location="${classes.dir}"/>

                </classpath>

            </junit>

        </target>

    </project>

    printsummary屬性會(huì)將測(cè)試的結(jié)果簡(jiǎn)單地顯示出來(lái),<test>name屬性是設(shè)定所要進(jìn)行測(cè)試的測(cè)試案例類。Ant構(gòu)建與調(diào)用JUnit進(jìn)行測(cè)試的信息如下:

    C:\workspace\B>ant
    Buildfile: build.xml
     
    setProperties:
     
    prepareDir:
        [mkdir] Created dir: C:\workspace\B\classes
     
    compile:
        [javac] Compiling 4 source files to C:\workspace\B\classes
     
    test:
        [junit] Running test.onlyfun.caterpillar.MathToolUnitTest
        [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0 sec
     
    BUILD SUCCESSFUL
    Total time: 1 second

    B.5 自動(dòng)生成測(cè)試報(bào)告

    接上一個(gè)主題,可以將JUnit的測(cè)試過(guò)程在Ant構(gòu)建過(guò)程中顯示出來(lái),只要加入< formatter>標(biāo)簽設(shè)定即可:

    <?xml version="1.0"?>
    <project name="autoBuildTest" default="test">
        ...
        <target name="test" depends="compile"> 
            <junit printsummary="yes"> 
                <formatter type="plain" usefile="false"/>
                <test 
                   name="test.onlyfun.caterpillar.MathToolUnitTest"/> 
                <classpath> 
                    <pathelement location="${classes.dir}"/> 
                </classpath> 
            </junit> 
        </target>
    </project>

    Ant構(gòu)建與調(diào)用JUnit進(jìn)行測(cè)試的信息如下:

    C:\workspace\B>ant
    Buildfile: build.xml
     
    setProperties:
     
    prepareDir:
       [delete] Deleting directory C:\workspace\B\classes
        [mkdir] Created dir: C:\workspace\B\classes
     
    compile:
        [javac] Compiling 4 source files to C:\workspace\B\classes
     
    test:
        [junit] Running test.onlyfun.caterpillar.MathToolUnitTest
        [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.016 sec
        [junit] Testsuite: test.onlyfun.caterpillar.MathToolUnitTest
        [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.016 sec
     
        [junit] Testcase: testGcd took 0.016 sec
     
    BUILD SUCCESSFUL
    Total time: 2 seconds

    當(dāng)usefile屬性設(shè)定為true時(shí),會(huì)自動(dòng)將產(chǎn)生的結(jié)果保存在文件中,默認(rèn)是TEST-*.txt。其中*是測(cè)試案例類名稱。就上例而言,所產(chǎn)生的報(bào)告文件內(nèi)容如下:

    Testsuite: test.onlyfun.caterpillar.MathToolUnitTest
    Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0 sec
     
    Testcase: testGcd took 0 sec

    <formatter>標(biāo)簽還可以設(shè)定將測(cè)試的結(jié)果,以XML文件保存下來(lái)。一個(gè)編寫的例子如下,它將測(cè)試的結(jié)果保存至report目錄中, 文件名稱為TEST-*.xml*是測(cè)試案例類名稱:

    <?xml version="1.0"?>
        ...
        <target name="test" depends="compile"> 
            <junit printsummary="yes"> 
                <formatter type="xml"/>
                <test 
                   name="test.onlyfun.caterpillar.MathToolUnitTest"/> 
                <classpath> 
                    <pathelement location="${classes.dir}"/> 
                </classpath> 
            </junit> 
        </target>
    </project>

    也可以將測(cè)試結(jié)果所產(chǎn)生的XML文件轉(zhuǎn)換為HTML文件,使用Ant可以直接完成這個(gè)工作。<junitreport>標(biāo)簽使用 XSLTXML文件轉(zhuǎn)換為HTML文件。下面的例子將前面的說(shuō)明作個(gè)總結(jié),以完整呈現(xiàn)編寫的實(shí)例:

    Ü build.xml

    <?xml version="1.0"?>

    <project name="autoBuildTest" default="report">

        <target name="setProperties">

            <property name="src.dir" value="src"/>

            <property name="classes.dir" value="classes"/>

            <property name="report.dir" value="report"/>       

        </target>

     

        <target name="prepareDir" depends="setProperties">

            <delete dir="${report.dir}"/>

            <delete dir="${classes.dir}"/>

            <mkdir dir="${report.dir}"/>

            <mkdir dir="${classes.dir}"/>

        </target>

     

        <target name="compile" depends="prepareDir">

            <javac srcdir="${src.dir}" destdir="${classes.dir}"/>

        </target> 

     

        <target name="test" depends="compile">

            <junit printsummary="yes">

                <formatter type="xml"/>

                <test

                   name="test.onlyfun.caterpillar.MathToolUnitTest"/>

                <classpath>

                    <pathelement location="${classes.dir}"/>

                </classpath>

            </junit>

        </target>

       

        <target name="report" depends="test">

            <junitreport todir="${report.dir}">

                <fileset dir="${report.dir}">

                    <include name="TEST-*.xml"/>

                </fileset>

                <report

                    format="frames" todir="${report.dir}/html"/>

            </junitreport>

        </target>   

    </project>

    <include>設(shè)定搜尋TEST-*.xml文件,將之轉(zhuǎn)換為HTML文件,而最后的結(jié)果被設(shè)定保存至report/html/目錄下,在format屬性中設(shè)定了HTML文件具有邊框(Frame),如果不設(shè)定這個(gè)屬性,則HTML報(bào)告文件就不具有邊框。在運(yùn)行Ant之后所產(chǎn)生的 HTML測(cè)試結(jié)果報(bào)告文件如圖B-2所示。

    B-2  Ant結(jié)合JUnit所自動(dòng)產(chǎn)生的測(cè)試報(bào)告

    附錄B只是對(duì)JUnit的一些簡(jiǎn)介,如果需要更多有關(guān)JUnit的資料,可以參考以下的網(wǎng)址:

    http://caterpillar.onlyfun.net/Gossip/JUnit/JUnitGossip.htm

    posted on 2008-01-08 10:03 九寶 閱讀(523) 評(píng)論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲色爱图小说专区| 美女裸身网站免费看免费网站| 特级毛片免费播放| 麻花传媒剧在线mv免费观看| 国产精品免费无遮挡无码永久视频| 999zyz**站免费毛片| 中文字幕免费视频精品一| 国产精品成人免费观看| 2022免费国产精品福利在线| 久久国产一片免费观看| a级毛片免费完整视频| 国产免费一区二区三区在线观看| 99久久国产精品免费一区二区| 免费无码av片在线观看| 无码国产精品一区二区免费模式 | 亚洲av日韩av无码| 免费a级毛片在线观看| 免费大学生国产在线观看p| 亚洲成A∨人片天堂网无码| 亚洲精品亚洲人成在线观看下载| 亚洲一区二区三区乱码A| 亚洲国产三级在线观看| 精品亚洲aⅴ在线观看| 2020天堂在线亚洲精品专区| 亚洲AV无码精品国产成人| 污网站免费在线观看| a级毛片毛片免费观看久潮喷| 日本在线看片免费人成视频1000| **毛片免费观看久久精品| 国产精品无码免费播放| 最近中文字幕2019高清免费| 免费看黄视频网站| 国产国产成年年人免费看片| 国产亚洲精品精品国产亚洲综合| 亚洲国产成人久久综合一| 亚洲精品伊人久久久久| 免费无码专区毛片高潮喷水| 久久九九AV免费精品| 免费看美女被靠到爽的视频| 国产亚洲美女精品久久久2020| 911精品国产亚洲日本美国韩国|