基于注釋的單元測試框架

發表于:2007-05-24來源:作者:點擊數: 標簽:框架測試單元這篇注釋
這篇文章將為大家介紹TestNG這個新的 測試框架 的特性,以及TestNG優于 Junit 3.X的地方。 TestNG(Test Next Generation),顧名思義,下一代的測試框架。它是基于J2SE5.0的注釋特性的而構建的輕量級的 單元測試 框架結構。說起單元測試框架,大家都會自然地
這篇文章將為大家介紹TestNG這個新的測試框架的特性,以及TestNG優于Junit3.X的地方。

TestNG(Test Next Generation),顧名思義,下一代的測試框架。它是基于J2SE5.0的注釋特性的而構建的輕量級的單元測試框架結構。說起單元測試框架,大家都會自然地聯想到JUnit。用過JUnit3.X的程序開發人員,都會發現JUnit在提供了強大功能的同時,也存在很多令人沮喪的地方。其中一個問題就是,JUnit3.x 在每個測試方法調用前和調用后都會調用setUp()和tearDown()的方法。如果開發人員希望在不同的測試方法中重用同一個JDBC連接或者JNDI的Context的時候,會覺得很不方便。一般的解決這個問題的方法是使用靜態方法,而這樣的話,就必須小心并發控制的問題(多個線程訪問共享的靜態對象)。除此之外,JUnit 3.X對于多線程測試也比較麻煩,需要其他模塊的支持。

這篇文章將為大家介紹TestNG這個新的測試框架的特性,以及TestNG優于Junit3.X的地方。眾所周知,Eclipse不僅僅是功能強大的Java IDE,同時也是一個開放的應用集成平臺。而Eclipse3.1提供了對J2SE5.0的支持。因此,筆者將以Eclipse為運行環境,介紹Testng的安裝,使用和運行。Eclipse3.1可以從http://www.eclipse.org/downloads/index.php下載。

關于注釋

由于TestNG是基于J2SE5.0的注釋特性所構建的。因此讀者在閱讀本文之前,必須了解注釋的一些基本概念。關于J2SE的注釋特性,筆者曾經在另一篇文章中詳細的介紹過,詳細介紹請參考"參考資料"。這里只簡單的介紹一些概念。

注釋是J2SE5.0所新提供的對于元數據的支持。程序開發人員可以在不改變原有邏輯的情況下,在源文件嵌入一些補充的信息。注釋都是由@Interface annotationName 來聲明的。注釋可以用來修飾類定義,方法,域變量等等。使用的時候是在修飾的對象的定義前@annotationName。注釋可以包含多個屬性,使用的時候為屬性賦值,例如 @annotationName(prop1=value1,prop2=value2)。程序的開發人員還可以通過Java的反射特性,在運行時獲得這些注釋的信息。在后面的章節中,大家會看到TestNG是如何使用它所定義的注釋類型的來實現測試框架的。





安裝TestNG

在Eclipse中安裝testNG很簡單。和安裝其他的plugin的方法相似。首先啟動Eclipse3.1,在Help->Software Update->Find and Install, 在彈出的向導中,選擇"Search New Features to Install", 點擊"New Remote Site",如圖1所示。在URL中輸入 http://beust.com/eclipse,點擊"OK"。如圖2所示,點擊"Finish",Eclipse會幫助你完成下面的安裝。熟悉Eclipse的讀者對這個過程一定不會覺得陌生。


圖1 新建Update Site
圖1 新建Update Site

圖2 安裝TestNG
圖2 安裝TestNG

安裝好TestNG后,在Eclipse中單擊"Window"->Show View->Other->Java->TestNG, TestNG的視圖就打開了。


圖3 TestNG的視圖
圖3 TestNG的視圖

注意:TestNG的視圖的作用時為了現實測試結果。為了顯示視圖的功能,圖3的視圖是運行了一個測試用例后的結果。讀者如果是第一次打開視圖,應該是空白的。





一個簡單的例子

TestNG和JUnit不同,他使用注釋、正則表達式和基于XML的配置文件對測試方法進行配置的。我們先來看一個簡單的例子。

1) 在Eclipse中創建一個Java的項目,com.catherine.lab.testng.demo

2) 在Packet Explorer中,右鍵點擊剛生成的項目,選擇Properties。

3) 在Properties屬性框中,選擇"Java Build Path",點擊"Add External JARs…"

4) 在文件瀏覽的對話框中,選擇{eclipse 3.1 home directory}/plugins/com.beust.testng.eclipse_XXX/eclipse_testng.jar,以及 {eclipse 3.1 home directory}/plugins/com.beust.testng.eclipse_XXX/lib/testng-jdk14.jar/以及testng-jdk15.jar. 點擊OK

5) 在Project中創建一個package: com.catherine.lab.testng.firstTest。在package里邊創建一個類:FristTestSample.


清單1 TestNG的第一個例子

            package com.catherine.lab.testng.firstTest;
            import com.beust.testng.annotations.*;
            public class FirstTestSample {
            public FirstTestSample() {
            super();
            }
            @Test
            public void testPass() {
            assert true :  "This test should pass.";
            }
            @Test
            public void testFail() {
            assert false : "This test will fail";
            }
            @Configuration(beforeTestClass = true)
            public void doBeforeTests() {
            System.out.println("invoke before test class!");
            }
            @Configuration(afterTestClass = true)
            public void doAfterTests() {
            System.out.println("invoke after test class!");
            }
            }
            

6) 在Eclipse中打開Run->Run..,如圖4所示。 首先在選擇使用TestNG的Project,而后在選擇編寫了測試邏輯的Class,點擊Run。測試結果就顯示在TestNG的視圖中了。如圖5所示。


圖4 配置運行TestNG的程序
圖4 配置運行TestNG的程序

圖5 TestNG的運行結果
圖5 TestNG的運行結果

這是一個完整的測試用例。和JUnit不同,TestNG中實現測試邏輯的類不需要繼承任何父類。測試方法也無需遵循testXXX的命名規則。

TestNG的類是大家所非常熟悉的普通的Java類,而在這個類中,所有的被@Test這個注釋所修飾的方法都會被當作測試方法來運行。除了測試類之外,TestNG還需要了一個配置文件,用來配置測試過程。以下是一個簡單的配置文件:testng.xml。


清單2 testNG的配置文件

            <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
            <suite name="My First TestNG test">
            <test name="Hello Test!">
            <classes>
            <class name=" com.catherine.lab.testng.firstTest.FirstTestSample " />
            </classes>
            </test>
            </suite>
            

testng.xml可以配置測試套件<suite>,類似于JUnit的TestSuite。而<test>類似于JUnit中的TestCase。所不同的是, TestNG中的測試套件可以包括多個測試用例,一個測試用例可以包括多個測試類,而一個測試類中可以定義多個測試方法。在下面的例子中,我們將看到這個配置文件更復雜的應用。

在圖4的運行配置中,我們也可以設置一個xml文件作為配置文件,而不是直接使用測試類。其實我們使用測試類的時候,testNG也幫我們生成了一個缺省的xml文件。不相信的話,你可以切換到Resource Perspective,然后刷新Workspace,就會發現這個project里邊生成了一個xml文件,而這個文件就是TestNG的缺省的配置文件。

現在我們再回到清單1,大家在上面的程序清單中會發現,除了使用@Test這個注釋以外,我們還使用了@Configuration這個注釋。下面我們就來介紹@Configuration這個注釋的用途。

在注釋Configuration中,定義了以下的屬性:


清單3 configuration中的屬性

            public boolean beforeSuite() default false;
            public boolean afterSuite() default false;
            public boolean beforeTest() default false;
            public boolean afterTest() default false;
            public boolean beforeTestClass() default false;
            public boolean afterTestClass() default false;
            public boolean beforeTestMethod() default false;
            public boolean afterTestMethod() default false;
            

  • beforeSuite=true,所修飾的方法將在測試套件(也就是配置文件中的Suite Tag)中任何一個方法調用之前,調用一次
  • afterSuite=true,所修飾的方法將在測試套件中所有方法都調用過后,調用一次
  • beforeTest=true,在測試用例(配置文件中Test Tag)中任何一個測試方法調用之前,調用一次
  • afterTest=true, 在測試用例中任何所有方法都調用之后,調用一次
  • beforeTestClass=true,在測試類中任何測試方法調用之前,調用一次
  • afterTestClass=true,在這個測試類中所有方法都調用過后,調用一次
  • beforeTestMethod=true,在每個測試方法調用之前,調用一次
  • afterTestMethod=true,在每個測試方法調用之后,調用一次

這個清單1中doBeforeTests()方法,在任何一個test方法調用之前被調用一次。doAfterTests,就是所有的test方法運行過了以后再調用一次。從Console輸出的信息中,我們可以驗證這一點:


圖6 console輸出的運行信息
 圖6 console輸出的運行信息




更復雜的例子

上一節中我們介紹了使用testNG的一個最簡單的例子,這一節中我們將介紹一些關于testNG的高級應用。注釋Test除了標志其修飾的方法為測試方法, 還提供了groups的屬性。比如上面例子的兩個方法testPass()和testFail(),我們可以給這兩個方法加上group的屬性。


清單4 測試@Test的groups屬性

                 @Test(groups={"functional_test"})
            public void testPass() {
            assert true :  "This test should pass.";
            }
            @Test(groups={"checkin_test"})
            public void testFail() {
            assert false : "This test will fail";
            }
            }
            

而后打開Run->Run…,在配置文件的Runtime配置中選擇Groups,然后選擇你要運行的group的名字。


圖7 運行選定的測試組
圖7 運行選定的測試組

這個時候我們從TestNG中看到測試結果,只有testPass運行了,而testFail因為不屬于funcational_test這個組,因此并沒有運行。


圖8 運行結果
圖8 運行結果

和第一個例子類似,雖然我們在這里并沒有顯示地定義配置文件,testNG已經生成了相應的配置文件了。在Resource Perspective底下可以看到這個文件:Custom_SuiteXXXX.xml.


清單5 自動生成的配置文件

            <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
            <suite name="My First TestNG test">
            <test name="Hello Test!">
            <groups>
            <run>
            <include name="functional_test"/>
            </run>
            </groups>
            <classes>
            <class name=" com.catherine.lab.testng.firstTest.FirstTestSample " />
            </classes>
            </test>
            </suite>
            

除了groups屬性以外,注釋Test還支持屬性dependsOnMethods和屬性dependsOnGroups. 這兩個屬性主要用于規定測試方法的執行順序。

TestNG并不保證按照定義的順序執行測試方法。如果這些測試方法之間有依賴關系的話,那么我們就可以使用dependsOnXXXX的屬性。我們還是看第一個例子,現在我們在這個例子里邊增加了一個方法:

setupEnvforPass()。我們希望setupEnvforPass()方法在testPass方法前執行,我們修改了testPass的test注釋。如清單6所示:


清單6 測試@Test的屬性dependsOnMethods

                @Test(groups={"functional_test"},
            dependsOnMethods = { "setEnvForPass" })
            public void testPass() {
            assert true :  "This test should pass.";
            }
            @Test(groups={"checkin_test"})
            public void testFail() {
            assert false : "This test will fail";
            }
            @Test(groups = {"init"})
            public void setEnvForPass(){
            assert true: "This is dependent method"
            }
            }
            

運行配置和配置文件都不需要改動,現在我們來運行這個例子,測試結果如圖9所示。大家可以看到,雖然我們在testPass方法之后定義了,setEnvForPass方法,但是由于我們將setEnvForPass定義為testPass的以來方法,setEnvForPass在testPass前執行了。

同樣,我們可以定義dependsOnGroups的屬性,這樣只有Groups中所有的方法都被執行完,這個方法才會被執行。注意:如果depensOnGroups中制定的group在配置文件中被excluded了,那么這個方法會依然被執行。但是如果指定的group在配置文件中被include了,而group中的方法有錯誤的話,那么這個方法會被skip,不會被執行。


圖9 運行結果
圖9 運行結果

下面我們要介紹一個新的注釋類型: @Parameter。

TestNG的測試方法可以帶有參數,參數可以通過@Parameter來聲明,具體的參數值在testng.xml中定義。這是testng的一個很優越的特性。我們還是在以前的例子上的基礎上來驗證這個特性。我們為setEnvForPass這個方法定義一個參數,target_server,并且在測試方法中打印這個參數。


清單7 測試注釋Parameter

            @Parameters({ "target_server" })
            @Test(groups = {"init"})
            public void setEnvForPass(String targetServer){
            assert true: "This is dependent method";
            System.out.println(targetServer);
            }
            }
            

Target_server的值在testng.xml中定義。在TestNG的運行時配置中選擇Suite,然后Browse清單8中定義好的的testng.xml。運行TestNG,我們從Console的運行結果中看到,target_server的值被打印出來了。


清單8 自定義的配置文件

            <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd">
            <suite name="Custom suite">
            <parameter name="target_server"  value="127.0.0.1"/>
            <test verbose="6" name="Test for 1 classes" annotations="1.5">
            <groups>
            <run>
            <include name="functional_test"/>
            </run>
            </groups>
            <classes>
            <class name="com.catherine.lab.testng.firstTest.FirstTestSample">
            </class>
            </classes>
            </test>
            </suite>
            

測試方法的參數可以是任意多個,只要你通過配置文件傳入了正確的參數,那么測試方法中就可以使用這些參數了。不過需要注意的是,參數是有作用域的,比如參數可以在配置文件的suite和test之后定義,而如果兩個參數的名稱一樣,test中定義的參數值有較高的優先級。

testNG可以從多個線程中運行測試方法,只需要將配置文件中suite的parallel屬性設為true。線程的數目在thread-count中設置。如果兩個方法有依賴關系,那么他們將在一個線程中運行,除此之外,都可以在多個線程中并發的運行。

<suite name="My suite" parallel="true" thread-count="10">

除了以上介紹的特性以外,(請參閱"參考資料")

  • TestNG提供了注釋Factory,用來動態生成測試方法的參數。
  • TestNG還提供了AntTask <testng>,可以從Ant腳本中調用testNG。
  • TestNG的可以調用JUnit的test cases。只需要配置文件中聲明
    <test name="Test1" junit="true">
    <classes ..>
  • TestNG還可以從程序中調用:
    TestNG testng = new TestNG();
    testng.setTestClasses(Class[] {});
    testng.run();

除了TestNG之外… 從上面的例子可以看出,TestNG這個單元測試框架的功能是很強大的,而且簡單易學。開發者只需要使用TestNG所提供的注釋和正確的配置文件,可以輕松地完成復雜的測試用例。

除了TestNG之外,JTiger也是一種基于J2SE5.0的單元測試框架,其中應用了大量J2SE5.0的新特性,比如注釋和靜態Import。和TestNG類似, JTiger提供了大量內建的注釋類型, 比如JTiger也使用注釋@Test標明測試方法, 使用注釋@Category表示這個測試方法屬于那一類,類似于TestNG的@Test的groups屬性。和TestNG不同的是,JTiger并沒有使外部的配置文件。

總之,TestNG和JTiger都解決了JUnit3.x中存在的問題,提供了大量優于JUnit3.x的特性。而JUnit也并沒有就此止步,即將發布的JUnit4.0有了根本性的變化,JUnit4.0也將變成基于注釋的測試系統。同樣也將提供大量的內建注釋類型:比如@Test, @Before, @After等等。這些引入的注釋類型,使得JUnit克服了以前的問題,擁有了新的活力。Justine Lee在他的文章中,詳細地比較了這三種測試框架,請參閱"參考資料"。

選用何種測試框架,取決于很多的因素。雖然JUnit具有眾多的擁簇者,但是TestNG和JTiger的崛起也不可小覷的。應該說,TestNG是建立在JUnit3.x之上的,吸取了JUnit的優點,同時也擯棄和改正了JUnit的缺點。筆者曾經在Eclipse中使用過JUnit3.x和TestNG,個人認為TestNG使用起來比JUnit3.x要更為方便。但是JUnit提供測試插件(plug-in)的功能,TestNG目前并沒有提供這種功能。不過我們有理由相信,在不久的將來TestNG會對于eclipse插件提供更為豐富的支持。本文通過對TestNG的介紹,希望能夠為大家在選擇測試框架的時候提供一個新的選擇。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97