JUnit 4快速入門(轉載)
JUnit 4快速入門
JUnit 4是JUnit框架有史以來的最大改進,其主要目標便是利用Java 5的Annotation特性簡化測試用例的編寫。讓我們看看如何使用JUnit 4來進行Unit測試。
請注意:本文主要介紹JUnit 4的最新特性和用法,並不會講解Unit測試的基礎。如果你對JUnit框架還不熟悉,請先參考“Eclipse快速上手指南 (2) 使用JUnit測試”一文,學習如何編寫JUnit測試。
我們使用的開發環境是Eclipse 3.2,它已經自帶了JUnit 4.1,你需要將JUnit 4 Library新增到專案用到的Library中。另外,必須使用JDK 5.0或更高版本。
要在Eclipse環境之外執行JUnit,需要下載JUnit 4.1,具體請訪問。
我們先看一個簡單的Math類:
package com.javaeedev.junit4;public class Math {
public int abs(int value) {
return value>=0 ? value : (-value);
}
public int div(int a, int b) {
return a / b;
}
/** * BUG: if b less than 0!
*/ public float exp(int a, int b) {
float r = 1;
for(int i=0; i r = r * a;
return r;
}
}
注意exp()方法是有Bug的,如果傳入引數2, -1,則期待的返回值應為0.5F,但實際返回值為1.0F。
下面我們看看傳統的JUnit的TestCase:
public class MathTest extends TestCase {
public void setUp() { super.setUp(); }
public void tearDown() { super.tearDown(); }
public void testAbs() { assertTrue(true); }
public void testDiv() {...}
public void testExp() {...}
}
JUnit依賴反射來執行每個以test開頭的方法。然而,在最新的JUnit 4中,由於有了Annotation的支援,我們的測試方法不需要再以testXxx標識了,而是寫上一個@Test標註即可。例如:
@Test public void doAbs() {...}
甚至MathTest類也不必繼承自TestCase。你也許會想到,不繼承自TestCase就無法呼叫assertXxx方法了,正因為如此,所有的assertXxx方法全部以靜態方法被放入了Assert類,使用Assert.assertXxx()呼叫。如果使用
import static org.junit.Assert.*;
則原有的程式碼不必改動。
setUp()和tearDown()方法也依賴@Before和@After標記,這樣做的最大的好處是在繼承體系內不必擔心忘記了在setUp()方法中呼叫父類的super.setUp()方法,JUnit框架會自動處理父類的@Before和@After標記的方法。
並且,JUnit框架對@Before和@After的呼叫順序類似於類的構造方法和析構方法,即@Before按照父類到子類的順序呼叫,@After則相反,這樣保證了資源的正確獲取和釋放。
當然,不再強迫必須使用setUp和tearDown作為方法名,可以使用更有意義的方法名,例如:initDatabase()和closeDatabase(),只要它們被標註了@Before和@After即可。
來看看使用Annotation的MathTest:
package com.javaeedev.junit4;
import static org.junit.Assert.*;
import org.junit.*;
public class MathTest {
public MathTest() {
System.out.println("new MathTest instance.");
}
@Before
public void setUp() throws Exception {
System.out.println("call @Before before a test method");
}
@After
public void tearDown() throws Exception {
System.out.println("call @After after a test method");
}
@Test
public void doAbs() {
Math math = new Math();
assertEquals(200, math.abs(200));
assertEquals(100, math.abs(-100));
assertEquals(0, math.abs(0));
}
@Test
public void doDiv() {
Math math = new Math();
assertEquals(5, math.div(100, 20));
assertEquals(4, math.div(100, 21));
}
@Test(expected=ArithmeticException.class)
public void doDiv0() {
new Math().div(127, 0);
}
@Test(timeout=1)
public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i++)
d+=i;
}
@Test
public void testExp() {
Math math = new Math();
assertEquals(32f, math.exp(2, 5), 0.001f);
assertEquals(1f, math.exp(2, 0), 0.001f);
assertEquals(0.5f, math.exp(2, (-1)), 0.001f);
}
}
對測試異常,JUnit 4可以用expected=Exception.class來期待一個預期的異常,而不必編寫
try {
...
fail("No exception");
}catch(Exception e) {
// OK!}
來看看doDiv0測試,我們期待一個除數為0的ArithmeticException,因此編寫如下測試方法:
@Test(expected=ArithmeticException.class)public void doDiv0() {
new Math().div(127, 0);
}
對於非常耗時的測試,@Test還有一個timeout來標識該方法最長執行時間,超過此時間即表示該測試方法失敗:
@Test(timeout=1)public void doLongTimeTask() {
double d = 0;
for(int i=1; i<10000000; i++)
d+=i;
}
以上方法若執行時間超過1ms則測試失敗,由於依賴CPU的執行速度,在不同的機器上測試結果也不同。
JUnit 4另一個較大的變化是引入了@BeforeClass和@AfterClass,它們在一個Test類的所有測試方法執行前後各執行一次。這是為了能在@BeforeClass中初始化一些昂貴的資源,例如資料庫連線,然後執行所有的測試方法,最後在@AfterClass中釋放資源。
正如你能想到的,由於@BeforeClass和@AfterClass僅執行一次,因此它們只能標記靜態方法,在所有測試方法中共享的資源也必須是靜態引用:
private static Object dbConnection;
@BeforeClasspublic static void setUpBeforeClass() throws Exception {
System.out.println("call @BeforeClass and init database connection");
dbConnection = new Object();
}
@AfterClasspublic static void tearDownAfterClass() throws Exception {
System.out.println("call @AfterClass to release database connection");
dbConnection = null;
}
最後執行測試用例,可以看到結果:
各個方法執行順序如下:
call @BeforeClass and init database connection
new MathTest instance.call @Before before a test method
call @After after a test method
new MathTest instance.call @Before before a test method
call @After after a test method
...
call @AfterClass to release database connection
可以看到,@BeforeClass是在例項化MathTest之前呼叫的,因此不能在構造方法中初始化共享資源。
最後需要注意的是由於Java 5的自動Box/Unbox特性,在呼叫assertEquals()時要特別注意,如果你傳入:
assertEquals(100F, 100);
則按照自動Box變為:
assertEquals(new Float(100F), new Integer(100));
測試失敗,因為Float類和Integer類不是同一型別。
因此要特別注意float和double的測試。事實上對float和double應使用
assertEquals(float, float, float delta);
assertEquals(double, double, double delta);
delta指定了兩個作比較的浮點數的相差範圍,在此範圍內的兩個浮點數將認為相等。可以傳入一個很小的數例如0.0001F。
JUnit 4非常適合使用Java 5的開發人員,但是無法在Java 1.4中獲得這些好處,並且,也不與以前的版本相容。因此,如果你正在使用Java 5,就可以考慮使用JUnit 4來編寫測試。
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10455649/viewspace-968048/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JUnit4小白入門
- JUnit入門
- CSS快速入門(轉)CSS
- Octave快速入門(4)——製圖
- Babel轉碼快速入門Babel
- Hibernate快速入門--轉
- Struts快速入門(二) (轉)
- Struts快速入門(三) (轉)
- Struts快速入門(四) (轉)
- 轉載:mybatis入門MyBatis
- COM入門(轉載)
- SQL語言快速入門(轉)SQL
- junit 4
- [轉載] Oracle EBS 入門Oracle
- redis 入門系列(轉載)Redis
- Util應用框架快速入門(4) - 整合測試開發入門框架
- JDBCTM 指南:入門4 - Statement (轉)JDBC
- log4j入門(轉)
- 快速載入系統檔案(轉)
- 快速排序快速入門排序
- J2EE入門(4) (轉)
- XML入門指南(4)XML元素(轉)XML
- Java Junit單元測試(入門必看篇)Java
- 自學前端如何快速入門?怎麼快速入門前端?前端
- 使用JMeter進行負載測試快速入門JMeter負載
- SQL快速入門 ( MySQL快速入門, MySQL參考, MySQL快速回顧 )MySql
- MySQL 快速入門MySql
- mysqlsla快速入門MySql
- Pipenv 快速入門
- Envoy 快速入門
- mongodb快速入門MongoDB
- Spark 快速入門Spark
- zookeeper 快速入門
- MQTT 快速入門MQQT
- Lumen快速入門
- Webpack快速入門Web
- RabbitMQ快速入門MQ
- QT快速入門QT