您的位置:軟件測試 > 開源軟件測試 > 開源單元測試工具 > junit
突破JUnit的局限
作者:網絡轉載 發(fā)布時間:[ 2012/11/29 14:57:15 ] 推薦標簽:

“沒有人喜歡bug。”大多數關于單元測試的文章以這句話開篇。的確,我們都希望代碼如設計的那樣準確地執(zhí)行,但是好像叛逆孩子一樣,程序在完成之后產生的行為將難以控制。比那些家長們幸運的是,我們可以運用工具以確保程序達到預期效果。

市面上有很多用于測試,分析以及debug程式的工具,其中以JUnit為有名。這是一個協(xié)助軟件工程師,QA(品質監(jiān)管)工程師測試階段性代碼的平臺。幾乎每個接觸過JUnit的人都對它有強烈的感情:要么喜歡,要么討厭。主要的抱怨之一是它缺少做復雜場景測試的能力。

通過突破傳統(tǒng)模式的思考,這一問題可以得到解決。這篇文章將介紹JUnit如何利用Pisces來實現復雜測試。Pisces是一個開源項目,作為JUnit的擴展,它可以讓你寫出由一些JUnit測試組成的測試單元,每個測試單元可以以串行或并行的方式運行在一個遠程主機上。Pisces可以讓你構成、運行復雜場景,并在一個地點協(xié)調它們。

JUnit 基礎

JUnit中有兩個基本對象,TestCase和TestSuite。TestCase通過提供一組方法來實現一系列測試。例如,setup()方法用來在每項測試開始前建立測試所需的測試環(huán)境,而teardown()方法用來在測試后銷毀該環(huán)境。其他的方法都會完成各式各樣的任務,例如,在測試中進行性能檢測,判斷變量是否為null,比較變量以及捕捉異常。

要創(chuàng)建測試程序,需要繼承TestCase類,覆寫setup和teardown方法,然后添加自己的測試函數,這些函數通常以“test測試名”的形式命名。

下面是一個測試程序的例子:
public class MyTestCase extends TestCase {
/**
* call super constructor with a test name
* string argument.
* @param testName the name of the method that
* should be run.
*/  public MyTestCase(String testName){
super(testName);
}
/**
* called before every test
* 在每項測試開始前被調用
*/  protected void setUp() throws Exception {
initSomething();
}
/**
* called after every test
* 在測試完成后被調用
*/  protected void tearDown() throws Exception {
finalizeSomething();
}
/**
* this method tests that ...
* 這個方法測試……
*/  public void testSomeTest1(){  ...  }
/**
* this method tests that ...
* 這個方法測試……
*/  public void testSomeTest2 (){
...
}
}

TestSuite是由幾個TestCase或其他的TestSuite構成的。你可以很容易的構成一個樹形測試,每個測試都由持有另外一些測試的TestSuite來構成。被加入到TestSuite中的測試在一個線程上依次被執(zhí)行。

ActiveTestSuite是TestSuite的一個子類。被添加到ActiveTestSuite中的測試程序以并行方式執(zhí)行,每個測試在一個獨立的線程上運行。創(chuàng)建一個測試單元的方法之一是繼承TestSuite類并覆寫suite()方法。

下面是一個簡單的例子:
public class MyTestSuite extends TestSuite {  public static Test suite() {
TestSuite suite =       new TestSuite("Test suite for ...");
// add the first test  // 添加第一個測試
MyTestCase mtc = new MyTestCase("testSomeTest1");
suite.addTest(mtc);
// add the second test  // 添加第一個測試
MyTestCase mtc2 =new MyTestCase("testSomeTest2");
suite.addTest(mtc2);
return suite;
}
}

運行一個測試或測試單元非常簡單,因為從JUnit提供的GUI開始,到所有的IDE開發(fā)環(huán)境,例如Eclipse,都有GUI可以使用。

圖1, 顯示了TestSuite在Eclipse中是如何表示的。
[[The No.1 Picture.]]
圖1,集成在Eclipse中的JUnit

因為介紹JUnit并不是這篇文章的主題,而且有很多關于JUnit的文章,本文只提供這些JUnit基礎概念的概要。在“資源”小節(jié)里有對JUnit更深入介紹的文章。

JUnit的優(yōu)點和缺點

JUnit是一個易用的,靈活的,開源的,測試平臺。像所有其他項目一樣,它有很多優(yōu)點,但也有不足之處。通過使用無需人工干預的JUnit自動測試平臺,我們很容易累積起大量的JUnit測試程序從而保證以往的bug不會重現。另外,JUnit便于和編譯單元(如,Ant)以及IDE單元(如,Eclipse)集成。

JUnit的弱點也眾所周知。它僅支持同步測試,而且不支持重現和其他異步單元。JUnit是一個黑箱測試平臺,因此測試那些不會直接影響功能的bug(例如,內存泄漏)非常困難。除此之外,它不支持易用的腳本語言,因此,想要使用JUnit要懂得Java。

JUnit的另一個不足是JUnit測試被限制于一個JVM之上。當要測試復雜或分布式場景的時候,這變成個大問題。本文剩下的部分,這個問題及其解決方法進行論述。

復雜場景測試:試復雜的分布式場景?

1. 那些確保小單元的完整性的測試很有用,但同時也有局限性。經驗告訴我們,大多數bug是在完整的測試中被發(fā)現的。這些問題從兩個模塊不能一同正常協(xié)調工作,到兩個獨立應用程序的異常。無論這是兩個應用服務,還是客戶/服務環(huán)境,甚至是點對點模式,對這些復雜場景的測試尤其重要,因為那些難纏的bug往往寄生于此。但是用JUnit對此幾乎無能為力。

2. 雖然Java具有平臺無關性,但測試一個應用程序在多種操作系統(tǒng)上的表現還是一個明智的選擇。你的程序可能在所有的操作系統(tǒng)上都能運行,但是卻不一定嚴格地按照你設計的那樣正常工作。在所有的操作系統(tǒng)上重復同樣的一組測試程序是一件耗時的工程,而用JUnit你不能進行分布式測試,因此你無法讓同樣的一組測試同時運行在幾個JVM之上,而每個JVM運行在不同的操作系統(tǒng)之上。

3. 一些單元代碼,只能在多JVM場景下被測試。例如,測試建立一個連接(TCP socket或者HTTP連接)以及從中取得的信息的完整性。這樣的測試不可能(或者說很難)在單一JVM上測試。而這是JUnit給我們的選擇。

用Ant協(xié)同測試

僅使用JUnit和Ant來協(xié)調幾個運行在不同JVM上的測試是可能的。Ant可以以并行或者串行的方式執(zhí)行任務(使用<parallel>標記),而且可以設置當有任何測試失敗的時候,停止運行。

但這種方法有其局限性,首先,使用JUnit和Ant 

軟件測試工具 | 聯系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網站地圖
滬ICP備07036474 2003-2017 版權所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd