JUnit 是JAVA語言事實上的標准測試庫JUnit 是三年以來最具裡程碑意義的一次發布它的新特性主要是針對JAVA中的標記(annotation)來簡化測試而不是利用子類反射或命名機制本文將講述如何使用JUnit 當前前提是你最好具有JUnit的使用經驗.
JUnit 由Kent Beck 和 Erich Gamma開發幾乎是JAVA開發最重要的第三方工具正如Martin Fowler 所說在軟件開發領域從來就沒有如此少的代碼起到了如此重要的作用由於JUnitJAVA代碼變得更健壯更可靠BUG也比以前更少由於JUnit (由Smalltalks的SUnit得來) 的出現隨後產生了許多xUnit的測試工具如nUnit (NET) pyUnit (Python) CppUnit (C++) dUnit (Delphi) 和其它不同平台及語言的測試相關的工具
雖然JUnit也只是一個工具但其產生的思想和技術卻較其架構更意義重大單元測試測試先行的編程方式測試驅動的開發方式並非必須由JUNIT實現也不一定要用SWing實現GUI界面JUNIT最近的一次更新是在三年前但它比其它大多數有BUG的框架都要健壯更重要的是JAVA一直在改進現在JAVA支持泛型枚舉可變長度參數以及標記語言(開創了開發可重用框架的新局面)
JUnits的停滯不前使得那些想要變革的開發人員換其它測試工具.挑戰者有Bill Venners的Artima SuiteRunner和Cedric Beust的TestNG.這些工具庫雖然有值得推薦的功能但沒有任何一款的地位能與JUNIT相比沒有任何一款工具被其它業界產品如Ant Maven Eclipse廣泛支持.因此Beck 和Gamma雙開始利用JAVA的新特性來開發新版的JUNIT目的是利用JAVA中的標記特性使得單元測試開發更容易Beck說JUNIT的主要目的是通過簡化JUNIT的使用鼓勵更多的開發人員寫更多的測試雖然會與以前的版本兼容但JUNIT與從JUNIT就開始的版本相比會有一個非常大的變化.
注意: 修改基本框架是一把雙刃劍雖然JUNIT的目的是清晰的但細節仍有許多不同因此本文只是一個簡單的介紹並不是最終文檔.
測試方法
以前所有版本的JUNIT都使用命名機制和反射來定位測試下面的代碼測試+=
import junitframeworkTestCase; public class AdditionTest extends TestCase { private int x = ; private int y = ; public void testAddition() { int z = x + y; assertEquals( z); } }
而在JUNIT 中測試方法由 @Test 標記說明如下
import orgjunitTest; import junitframeworkTestCase; public class AdditionTest extends TestCase { private int x = ; private int y = ; @Test public void testAddition() { int z = x + y; assertEquals( z); } }
使用標記的好處是你不用將所有測試方法命名為 testFoo() testBar()等等以test\開頭的方法下面的方法也同樣可以工作 import orgjunitTest; import junitframeworkTestCase; public class AdditionTest extends TestCase { private int x = ; private int y = ; @Test public void additionTest() { int z = x + y; assertEquals( z); } }
下面的代碼也同樣正確
import orgjunitTest; import junitframeworkTestCase; public class AdditionTest extends TestCase { private int x = ; private int y = ; @Test public void addition() { int z = x + y; assertEquals( z); } }
這種命名機制最大的優點是更適合你的待測試類或方法名稱例如你可以使用ntains()測試 ntains() ;使用ListTestaddAll()測試 Listadd()等等.
TestCase 還可以繼續使用但你沒有必須再擴展為子類只要你聲明了@Test你可以將測試方法放在任何類中當然如要訪問assert等方法你必須要引用junitAssert類如下
import orgjunitAssert; public class AdditionTest { private int x = ; private int y = ; @Test public void addition() { int z = x + y; AssertassertEquals( z); } }
你也可以使用JDK中的新特性(static import)使得跟以前版本一樣簡單
import static orgjunitAssertassertEquals; public class AdditionTest { private int x = ; private int y = ; @Test public void addition() { int z = x + y; assertEquals( z); } }
這種方法測試受保護的方法非常容易因為你可以在測試類中繼承有受保護方法的類.
SetUp 和TearDown
JUnit 中 test runners 會在每個測試之前自動調用 setUp()方法此方法主要用於初始化變量打開日志重置環境變量等下面是XOMs XSLTransformTest中的 setUp()方法
protected void setUp() { SystemsetErr(new PrintStream(new ByteArrayOutputStream())); inputDir = new File(data); inputDir = new File(inputDir xslt); inputDir = new File(inputDir input); }
在JUnit 中你仍然可以在每個測試前初始化變量和配置環境然而這些操作可以不用在Setup()中完成你可以在初始化方法前面添加 @Beforer 來表示如下
@Before protected void initialize() { SystemsetErr(new PrintStream(new ByteArrayOutputStream())); inputDir = new File(data); inputDir = new File(inputDir xslt); inputDir = new File(inputDir input); }
你也可以有多個方法標記有@Before所有方法都會在每個測試之前執行
@Before protected void findTestDataDirectory() { inputDir = new File(data); inputDir = new File(inputDir xslt); inputDir = new File(inputDir input); } @Before protected void redirectStderr() { SystemsetErr(new PrintStream(new ByteArrayOutputStream())); }
清除環境與JUNIT 差不多在JUNIT中使用 tearDown()方法下面的代碼是結束測試時回收內存
protected void tearDown() { doc = null; Systemgc(); }
在JUnit 中你還可以使用 @After 標記來說明
@After protected void disposeDocument() { doc = null; Systemgc(); }
與 @Before一樣你也可以有多個標記有 @After的清除方法每個都會在執行完每個測試後執行
最後你不需要在父類中明確調用這些初始化或清除方法.test runner會自動調用這些標記的方法.子類中的@Before方法在父類的@Before方法之後執行(這與構造函數的執行順序一樣)而@After方法剛好相反子類中的@After方法先執行.然而多個@Before和@After方法的執行順序就是未知的.
From:http://tw.wingwit.com/Article/program/Java/ky/201311/27946.html