1. 單元測試是什麼簡單介紹一下單元測試
工廠在組裝一台電視機之前,會對每個元件都進行測試,這,就是單元測試。
其實我們每天都在做單元測試。你寫了一個函數,除了極簡單的外,總是要執行一下,看看功能是否正常,有時還要想辦法輸出些數據,如彈出信息窗口什麼的,這,也是單元測試,老納把這種單元測試稱為臨時單元測試。只進行了臨時單元測試的軟體,針對代碼的測試很不完整,代碼覆蓋率要超過70%都很困難,未覆蓋的代碼可能遺留大量的細小的錯誤,這些錯誤還會互相影響,當BUG暴露出來的時候難於調試,大幅度提高後期測試和維護成本,也降低了開發商的競爭力。可以說,進行充分的單元測試,是提高軟體質量,降低開發成本的必由之路。
對於程序員來說,如果養成了對自己寫的代碼進行單元測試的習慣,不但可以寫出高質量的代碼,而且還能提高編程水平。
要進行充分的單元測試,應專門編寫測試代碼,並與產品代碼隔離。老納認為,比較簡單的辦法是為產品工程建立對應的測試工程,為每個類建立對應的測試類,為每個函數(很簡單的除外)建立測試函數。首先就幾個概念談談老納的看法。
一般認為,在結構化程序時代,單元測試所說的單元是指函數,在當今的面向對象時代,單元測試所說的單元是指類。以老納的實踐來看,以類作為測試單位,復雜度高,可操作性較差,因此仍然主張以函數作為單元測試的測試單位,但可以用一個測試類來組織某個類的所有測試函數。單元測試不應過分強調面向對象,因為局部代碼依然是結構化的。單元測試的工作量較大,簡單實用高效才是硬道理。
有一種看法是,只測試類的介面(公有函數),不測試其他函數,從面向對象角度來看,確實有其道理,但是,測試的目的是找錯並最終排錯,因此,只要是包含錯誤的可能性較大的函數都要測試,跟函數是否私有沒有關系。對於C++來說,可以用一種簡單的方法區隔需測試的函數:簡單的函數如數據讀寫函數的實現在頭文件中編寫(inline函數),所有在源文件編寫實現的函數都要進行測試(構造函數和析構函數除外)。
什麼時候測試?單元測試越早越好,早到什麼程度?XP開發理論講究TDD,即測試驅動開發,先編寫測試代碼,再進行開發。在實際的工作中,可以不必過分強調先什麼後什麼,重要的是高效和感覺舒適。從老納的經驗來看,先編寫產品函數的框架,然後編寫測試函數,針對產品函數的功能編寫測試用例,然後編寫產品函數的代碼,每寫一個功能點都運行測試,隨時補充測試用例。所謂先編寫產品函數的框架,是指先編寫函數空的實現,有返回值的隨便返回一個值,編譯通過後再編寫測試代碼,這時,函數名、參數表、返回類型都應該確定下來了,所編寫的測試代碼以後需修改的可能性比較小。
由誰測試?單元測試與其他測試不同,單元測試可看作是編碼工作的一部分,應該由程序員完成,也就是說,經過了單元測試的代碼才是已完成的代碼,提交產品代碼時也要同時提交測試代碼。測試部門可以作一定程度的審核。
關於樁代碼,老納認為,單元測試應避免編寫樁代碼。樁代碼就是用來代替某些代碼的代碼,例如,產品函數或測試函數調用了一個未編寫的函數,可以編寫樁函數來代替該被調用的函數,樁代碼也用於實現測試隔離。採用由底向上的方式進行開發,底層的代碼先開發並先測試,可以避免編寫樁代碼,這樣做的好處有:減少了工作量;測試上層函數時,也是對下層函數的間接測試;當下層函數修改時,通過回歸測試可以確認修改是否導致上層函數產生錯誤。
2. Spring Boot 微服務非同步調用 @EnableAsync @Async
第一步:在Application啟動類上面加上@EnableAsync註解
第二步:定義[線程池]
第三步:在非同步方法上添加@Async
第四步:測試
輸出結果:
時間testA:2
開始testB
開始testA
完成testA
完成testB
任務testA,當前線程:async-thread-pool-1
時間testB:3002
非同步方法@Async註解失效情況:
(1)在@SpringBootApplication啟動類沒有添加註解@EnableAsync
(2)調用方法和非同步方法寫在同一個類,需要在不同的類才能有效。
(2)調用的是靜態(static )方法
(3)調用(private)私有化方法
個別失效報錯情況:
報錯一:提示需要在@EnableAsync上設置proxyTargetClass=true來強制使用基於cglib的代理。註解上加上即可。
3. 求問淺談:怎麼為私有方法寫單元測試
為私有方法寫單元測試:new一個對象,設好入口參數後,調用這個方法,比較期望值和實際值即可。給一個類的私有方法做單元測試,也不麻煩,先通過反射獲取這個方法,然後將這個方法的可訪問性強制設為true,這樣的話,這個私有方法就可以被調用了。
代碼如下:
//被測試方法
private Double format(Double fileSize){
Double size = fileSize;
size = size / 1024 / 1024;
size = (int)(size.doubleValue() * 10 + 0.5) / 10.0;
return size;
}
@Test
public void testFormat(){
ClientDownloadAction action = new ClientDownloadAction();
double size = 3732930;
Class class1 = action.getClass();
try {
Method format = class1.getDeclaredMethod("format", Double.class);
format.setAccessible(true);//設為可見
Double result = (Double)format.invoke(action, size);
Double expect = 3.6;
Assert.assertEquals(expect, result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4. Java,私有方法做Junit單元測試,私有方法中注入了其他的bean,運行時,這個bean為空,沒有注入
這種情況一般有模擬程序來實現。junit有很多擴展的包。例如dbunit等。
5. private className(){}單元測試如何覆蓋
我們知道可以通過反射method.invoke來調用某個方法,但如果方法前面為private怎麼辦呢?我們可以使用method.setAccessible(true);來跳過安全檢查,就可以調用private方法了。原理就這么簡單。
Java的反射(reflection)機制是指在程序的運行狀態中,可以構造任意一個類的對象,可以了解任意一個對象所屬的類,可以了解任意一個類的成員變數和方法,可以調用任意一個對象的屬性和方法。這種動態獲取程序信息以及動態調用對象的功能稱為Java語言的反射機制。反射被視為動態語言的關鍵。
6. 怎樣使用Junit Framework進行單元測試的編寫
1. 單元測試的編寫原則
Junit 附帶文檔所列舉的單元測試帶有一定的迷惑性,因為幾乎所有的示例單元都是針對某個對象的某個方法,似乎 Junit 的單元測試僅適用於類組織結構的靜態約束,從而使初學者懷疑 Junit 下的單元測試所能帶來的效果。因此我們需要重新定義如何確定有價值的單元測試以及如何編寫這些單元測試、維護這些單元測試,從而讓更多的程序員接受和熟悉 Junit 下的單元測試的編寫。
在 Junit 單元測試框架的設計時,作者一共設定了三個總體目標,第一個是簡化測試的編寫,這種簡化包括測試框架的學習和實際測試單元的編寫;第二個是使測試單元保持持久性;第三個則是可以利用既有的測試來編寫相關的測試。從這三個目標可以看出,單元測試框架的基本設計考慮依然是從我們現有的測試方式和方法出發,而只是使測試變得更加容易實施和擴展並保持持久性。因此編寫單元測試的原則可以從我們通常使用的測試方法借鑒和利用。
回頁首
2. 如何確定單元測試
在我們通常的測試中,一個單元測試一般針對於特定對象的一個特定特性,譬如,假定我們編寫了一個針對特定資料庫訪問的連接池的類包實現,我們會建立以下的單元測試:
在連接池啟動後,是否根據定義的規則在池中建立了相應數量的資料庫連接
申請一個資料庫連接,是否根據定義的規則從池中直接獲得緩存連接的引用,還是建立新的連接
釋放一個資料庫連接後,連接是否根據定義的規則被池釋放或者緩存以便以後使用
後台 Housekeeping 線程是否按照定義的規則釋放已經過期的連接申請
如果連接有時間期限,後台 Housekeeping 線程是否定期釋放已經過期的緩存連接
這兒只列出了部分的可能測試,但是從這個列表我們可以看出單元測試的粒度。一個單元測試基本是以一個對象的明確特性為基礎,單元測試的過程應該限定在一個明確的線程范圍內。根據上面所述,一個單元測試的測試過程非常類似於一個 Use Case 的定義,但是單元測試的粒度一般來說比 Use Case 的定義要小,這點是容易理解的,因為 Use Case 是以單獨的事務單元為基礎的,而單元測試是以一組聚合性很強的對象的特定特徵為基礎的,一般而言一個事務中會利用許多的系統特徵來完成具體的軟體需求。
從上面的分析我們可以得出,測試單元應該以一個對象的內部狀態的轉換為基本編寫單元。一個軟體系統就和一輛設計好的汽車一樣,系統的狀態是由同一時刻時系統內部的各個分立的部件的狀態決定的,因此為了確定一個系統最終的行為符合我們起始的要求,我們首先需要保證系統內的各個部分的狀態會符合我們的設計要求,所以我們的測試單元的重點應該放在確定對象的狀態變換上。
然而需要注意的並不是所有的對象組特徵都需要被編寫成獨立的測試單元,如何在對象組特徵里篩選有價值的測試單元的原則在 JUnitTest Infected: Programmers Love Writing Tests 一文中得到了正確的描述,你應該在有可能引入錯誤的地方引入測試單元,通常這些地方存在於有特定邊界條件、復雜演算法以及需求變動比較頻繁的代碼邏輯中。除了這些特性需要被編寫成獨立的測試單元外,還有一些邊界條件比較復雜的對象方法也應該被編寫成獨立的測試單元,這部分單元測試已經在 Junit 文檔中被較好的描述和解釋過了。
在基本確定了需要編寫的單元測試,我們還應該問自己:編寫好了這些測試,我們是否可以有把握地告訴自己,如果代碼通過了這些單元測試,我們能認定程序的運行是正確的,符合需求的。如果我們不能非常的確定,就應該看看是否還有遺漏的需要編寫的單元測試或者重新審視我們對軟體需求的理解。通常來說,在開始使用單元測試的時候,更多的單元測試總是沒有錯的。
一旦我們確定了需要被編寫的測試單元,接下來就應該
回頁首
3. 如何編寫單元測試
在 XP 下強調單元測試必須由類包的編寫者負責編寫,這個限定對於我們設定的測試目標是必須的。因為只有這樣,測試才能保證對象的運行時態行為符合需求,而僅通過類介面的測試,我們只能確保對象符合靜態約束,因此這就要求我們在測試的過程中,必須開放一定的內部數據結構,或者針對特定的運行行為建立適當的數據記錄,並把這些數據暴露給特定的測試單元。這也就是說我們在編寫單元測試時必須對相應的類包進行修改,這樣的修改也發生在我們以前使用的測試方法中,因此以前的測試標記及其他一些測試技巧仍然可以在 Junit 測試中改進使用。
由於單元測試的總體目標是負責我們的軟體在運行過程中的正確無誤,因此在我們對一個對象編寫單元測試的時候,我們不但需要保證類的靜態約束符合我們的設計意圖,而且需要保證對象在特定的條件下的運行狀態符合我們的預先設定。還是拿資料庫緩沖池的例子說明,一個緩沖池暴露給其他對象的是一組使用介面,其中包括對池的參數設定、池的初始化、池的銷毀、從這個池裡獲得一個數據連接以及釋放連接到池中,對其他對象而言隨著各種條件的觸發而引起池的內部狀態的變化是不需要知道的,這一點也是符合封裝原理的。但是池對象的狀態變化,譬如:緩存的連接數在某些條件下會增長,一個連接在足夠長的運行後需要被徹底釋放從而使池的連接被更新等等,雖然外部對象不需要明確,但是卻是程序運行正確的保證,所以我們的單元測試必須保證這些內部邏輯被正確的運行。
編譯語言的測試和調試是很難對運行的邏輯過程進行跟蹤的,但是我們知道,無論邏輯怎麼運行,如果狀態的轉換符合我們的行為設定,那驗證結果顯然是正確的,因此在對一個對象進行單元測試的時候,我們需要對多數的狀態轉換進行分析和對照,從而驗證對象的行為。狀態是通過一系列的狀態數據來描述的,因此編寫單元測試首先分析出狀態的變化過程(狀態轉換圖對這個過程的描述非常清晰),然後根據狀態的定義確定分析的狀態數據,最後是提供這些內部的狀態數據的訪問。在資料庫連接池的例子中,我們對池實現的對象 DefaultConnectionProxy 的狀態變換進行分析後,我們決定把表徵狀態的 OracleConnectionCacheImpl 對象公開給測試類。參見示例一
示例一
/**
* 這個類簡單的包裝了 oracle 對數據連接緩沖池的實現。
*
*/
public class DefaultConnectionProxy extends ConnectionProxy {
private static final String name = "Default Connection Proxy";
private static final String description =
"這個類簡單的包裝了 oracle 對數據連接緩沖池的實現。";
private static final String author = "Ion-Global.com";
private static final int major_version = 0;
private static final int minor_version = 9;
private static final boolean pooled = true;
private ConnectionBroker connectionBroker = null;
private Properties props;
private Properties propDescriptions;
private Object initLock = new Object();
// Test Code Begin...
/* 為了能夠了解對象的狀態變化,因此需要把表徵對象內部狀態變化的部分私有變數提
供公共的訪問介面(或者提供讓同一個類包的訪問介面),以便使測試單元可以有效地
判斷對象的狀態轉變,在本示例中對包裝的 OracleConnectionCacheImpl 對象提供訪問
介面。
*/
OracleConnectionCacheImpl getConnectionCache() {
if (connectionBroker == null) {
throw new IllegalStateException("You need start the server first.");
}
return connectionBroker.getConnectionCache();
}
// Test Code End...
在公開內部狀態數據後,我們就可以編寫我們的測試單元了,單元測試的選擇方法和選擇尺度已經在本文前面章節進行了說明,但是仍然需要注意的是,由於 assert 方法會拋出一個 error,你應該在測試方法的最後集中用 assert 相關方法進行判斷,這樣可以確保資源得到釋放。
對資料庫連接池的例子,我們可以建立測試類 DefaultConnectionProxyTest,同時建立數個 test case,如下:
示例二
/**
* 這個類對示例一中的類進行簡單的測試。
*
*/
public class DefaultConnectionProxyTest extends TestCase {
private DefaultConnectionProxy conProxy = null;
private OracleConnectionCacheImpl cacheImpl = null;
private Connection con = null;
/** 設置測試的 fixture,建立必要的測試起始環境。
*/
protected void setUp() {
conProxy = new DefaultConnectionProxy();
conProxy.start();
cacheImpl = conProxy.getConnectionCache();
}
/** 對示例一中的對象進行服務啟動後的狀態測試,檢查是否在服務啟動後,
連接池的參數設置是否正確。
*/
public void testConnectionProxyStart() {
int minConnections = 0;
int maxConnections = 0;
assertNotNull(cacheImpl);
try {
minConnections = Integer.parseInt(PropertyManager.getProperty
("DefaultConnectionProxy.minConnections"));
maxConnections = Integer.parseInt(PropertyManager.getProperty
("DefaultConnectionProxy.maxConnections"));
} catch (Exception e) {
// ignore the exception
}
assertEquals(cacheImpl.getMinLimit(), minConnections);
assertEquals(cacheImpl.getMaxLimit(), maxConnections);
assertEquals(cacheImpl.getCacheSize(), minConnections);
}
/** 對示例一中的對象進行獲取資料庫連接的測試,看看是否可以獲取有效的資料庫連接,
並且看看獲取連接後,連接池的狀態是否按照既定的策略進行變化。由於 assert 方法拋出的是
error 對象,因此盡可能把 assert 方法放置到方法的最後集體進行測試,這樣在方法內打開的
資源,才能有效的被正確關閉。
*/
public void testGetConnection() {
int cacheSize = cacheImpl.getCacheSize();
int activeSize = cacheImpl.getActiveSize();
int cacheSizeAfter = 0;
int activeSizeAfter = 0;
con = conProxy.getConnection();
if (con != null) {
activeSizeAfter = cacheImpl.getActiveSize();
cacheSizeAfter = cacheImpl.getCacheSize();
try {
con.close();
} catch (SQLException e) {
}
} else {
assertNotNull(con);
}
/* 如果連接池中的實際使用連接數小於緩存連接數,檢查獲取的新的數據連接是否
從緩存中獲取,反之連接池是否建立新的連接
*/
if (cacheSize > activeSize) {
assertEquals(activeSize + 1, activeSizeAfter);
assertEquals(cacheSize, cacheSizeAfter);
} else {
assertEquals(activeSize + 1, cacheSizeAfter);
}
}
/** 對示例一中的對象進行資料庫連接釋放的測試,看看連接釋放後,連接池的
狀態是否按照既定的策略進行變化。由於 assert 方法拋出的是 error 對象,因此盡可
能把 assert 方法放置到方法的最後集體進行測試,這樣在方法內打開的
資源,才能有效的被正確關閉。
*/
public void testConnectionClose() {
int minConnections = cacheImpl.getMinLimit();
int cacheSize = 0;
int activeSize = 0;
int cacheSizeAfter = 0;
int activeSizeAfter = 0;
con = conProxy.getConnection();
if (con != null) {
cacheSize = cacheImpl.getCacheSize();
activeSize = cacheImpl.getActiveSize();
try {
con.close();
} catch (SQLException e) {
}
activeSizeAfter = cacheImpl.getActiveSize();
cacheSizeAfter = cacheImpl.getCacheSize();
} else {
assertNotNull(con);
}
assertEquals(activeSize, activeSizeAfter + 1);
/* 如果連接池中的緩存連接數大於最少緩存連接數,檢查釋放數據連接後是否
緩存連接數比之前減少了一個,反之緩存連接數是否保持為最少緩存連接數
*/
if (cacheSize > minConnections) {
assertEquals(cacheSize, cacheSizeAfter + 1);
} else {
assertEquals(cacheSize, minConnections);
}
}
/** 釋放建立測試起始環境時的資源。
*/
protected void tearDown() {
cacheImpl = null;
conProxy.destroy();
}
public DefaultConnectionProxyTest(String name) {
super(name);
}
/** 你可以簡單的運行這個類從而對類中所包含的測試單元進行測試。
*/
public static void main(String args[]) {
junit.textui.TestRunner.run(DefaultConnectionProxyTest.class);
}
}
當單元測試完成後,我們可以用 Junit 提供的 TestSuite 對象對測試單元進行組織,你可以決定測試的順序,然後運行你的測試。
7. 軟體工程單元測試應該怎麼寫
。。。。。。。。。。。。。。。。
8. 單元測試的測試工具
現在開始介紹單元測試工具,分別按編程語言進行分組介紹。 CppUnit
首先是CppUnit,這是C++單元測試工具的鼻祖,免費的開源的單元測試框架。由於已有一眾高人寫了不少關於CppUnit的很好的文章,老納就不現丑了,想了解CppUnit的朋友,建議讀一下Cpluser 所作的《CppUnit測試框架入門》,。該文也提供了CppUnit的下載地址。
C++Test
然後介紹C++Test,這是Parasoft公司的產品。[C++Test是一個功能強大的自動化C/C++單元級測試工具,可以自動測試任何C/C++函數、類,自動生成測試用例、測試驅動函數或樁函數,在自動化的環境下極其容易快速的將單元級的測試覆蓋率達到100%]。[]內的文字引自,這是華唐公司的網頁。老納想寫些介紹C++Test的文字,但發現無法超越華唐公司的網頁上的介紹,所以也就省點事了,想了解C++Test的朋友,建議訪問該公司的網站。華唐公司代理C++Test,想要購買或索取報價、試用版都可以找他們。
Visual Unit
最後介紹Visual Unit,簡稱VU,這是國產的單元測試工具,據說申請了多項專利,擁有一批創新的技術,不過老納只關心是不是有用和好用。[自動生成測試代碼 快速建立功能測試用常式序行為一目瞭然 極高的測試完整性 高效完成白盒覆蓋 快速排錯 高效調試 詳盡的測試報告]。[]內的文字是VU開發商的網頁上摘錄的,。前面所述測試要求:完成功能測試,完成語句覆蓋、條件覆蓋、分支覆蓋、路徑覆蓋,用VU可以輕松實現,還有一點值得一提:使用VU還能提高編碼的效率,總體來說,在完成單元測試的同時,編碼調試的時間還能大幅度縮短。算了,不想再講了,老納顯擺理論、介紹經驗還是有興趣的,因為可以滿足老納好為人師的虛榮心,但介紹工具就覺得索然無味了,畢竟工具好不好用,合不合用,要試過才知道,還是自己去開發商的網站看吧,可以下載演示版,還有演示課件。
gtest
gtest測試框架是在不同平台上(Linux,Mac OS X,Windows,Cygwin,Windows CE和Symbian)為編寫C++測試而生成的。它是基於xUnit架構的測試框架,支持自動發現測試,豐富的斷言集,用戶定義的斷言,death測試,致命與非致命的失敗,類型參數化測試,各類運行測試的選項和XML的測試報告。需要詳細了解的朋友可以參閱《玩轉Google單元測試框架gtest系列》該篇文章。 JUnit
JUnit 是 Java 社區中知名度最高的單元測試工具。它誕生於 1997 年,由 Erich Gamma 和 Kent Beck 共同開發完成。其中 Erich Gamma 是經典著作《設計模式:可復用面向對象軟體的基礎》一書的作者之一,並在 Eclipse 中有很大的貢獻;Kent Beck 則是一位極限編程(XP)方面的專家和先驅。JUnit 設計的非常小巧,但是功能卻非常強大。JUnit ——是一個開發源代碼的Java測試框架,用於編寫和運行可重復的測試。他是用於單元測試框架體系xUnit的一個實例(用於java語言)。主要用於白盒測試,回歸測試。
JUnit的好處和JUnit單元測試編寫原則:
好處:可以使測試代碼與產品代碼分開;針對某一個類的測試代碼通過較少的改動便可以應用於另一個類的測試;易於集成到測試人員的構建過程中,JUnit和Ant的結合可以實施增量開發;JUnit是公開源代碼的,可以進行二次開發;可以方便地對JUnit進行擴展;
編寫原則:是簡化測試的編寫,這種簡化包括測試框架的學習和實際測試單元的編寫;是使測試單元保持持久性;是可以利用既有的測試來編寫相關的測試;
JUnit使用幫助
1、junit3.x版本,我們通常使用junit 3.8
(1)、使用junit3.x版本進行單元測試時,測試類必須要繼承於TestCase父類;
(2)、測試方法需要遵循的原則:
A、public的
B、void的
C、無方法參數
D、方法名稱必須以test開頭
(3)、不同的Test Case之間一定要保持完全的獨立性,不能有任何的關聯。
(4)、我們要掌握好測試方法的順序,不能依賴於測試方法自己的執行順序。
dome:
public class TestMyNumber extends TestCase {
private MyNumber myNumber;
public TestMyNumber(String name) {
super(name);
}
// 在每個測試方法執行 [之前] 都會被調用
@Override
public void setUp() throws Exception {
// System.out.println(歡迎使用Junit進行單元測試…);
myNumber = new MyNumber();
}
// 在每個測試方法執行 [之後] 都會被調用
@Override
public void tearDown() throws Exception {
// System.out.println(Junit單元測試結束…);
}
public void testDivideByZero() {
Throwable te = null;
try {
myNumber.divide(6, 0);
Assert.fail(測試失敗);
} catch (Exception e) {
e.printStackTrace();
te = e;
}
Assert.assertEquals(Exception.class, te.getClass());
Assert.assertEquals(除數不能為 0 , te.getMessage());
}
}
2、junit4.x版本
(1)、使用junit4.x版本進行單元測試時,不用測試類繼承TestCase父類,因為,junit4.x全面引入了Annotation來執行我們編寫的測試。
(2)、junit4.x版本,引用了註解的方式,進行單元測試;
(3)、junit4.x版本我們常用的註解:
A、@Before 註解:與junit3.x中的setUp()方法功能一樣,在每個測試方法之前執行;
B、@After 註解:與junit3.x中的tearDown()方法功能一樣,在每個測試方法之後執行;
C、@BeforeClass 註解:在所有方法執行之前執行;
D、@AfterClass 註解:在所有方法執行之後執行;
E、@Test(timeout = xxx) 註解:設置當前測試方法在一定時間內運行完,否則返回錯誤;
F、@Test(expected = Exception.class) 註解:設置被測試的方法是否有異常拋出。拋出異常類型為:Exception.class;
G、@Ignore 註解:注釋掉一個測試方法或一個類,被注釋的方法或類,不會被執行。
dome:
package com.an.junit;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestMyNumber {
private MyNumber myNumber;
@BeforeClass
// 在所有方法執行之前執行
public static void globalInit() {
System.out.println(init all method...);
}
@AfterClass
// 在所有方法執行之後執行
public static void globalDestory() {
System.out.println(destory all method...);
}
@Before
// 在每個測試方法之前執行
public void setUp() {
System.out.println(start setUp method);
myNumber = new MyNumber();
}
@After
// 在每個測試方法之後執行
public void tearDown() {
System.out.println(end tearDown method);
}
@Test(timeout=600)// 設置限定測試方法的運行時間 如果超出則返回錯誤
public void testAdd() {
System.out.println(testAdd method);
int result = myNumber.add(2, 3);
assertEquals(5, result);
}
@Test
public void testSubtract() {
System.out.println(testSubtract method);
int result = myNumber.subtract(1, 2);
assertEquals(-1, result);
}
@Test
public void testMultiply() {
System.out.println(testMultiply method);
int result = myNumber.multiply(2, 3);
assertEquals(6, result);
}
@Test
public void testDivide() {
System.out.println(testDivide method);
int result = 0;
try {
result = myNumber.divide(6, 2);
} catch (Exception e) {
fail();
}
assertEquals(3, result);
}
@Test(expected = Exception.class)
public void testDivide2() throws Exception {
System.out.println(testDivide2 method);
myNumber.divide(6, 0);
fail(test Error);
}
public static void main(String[] args) {
}
}
有興趣的朋友可以下下來仔細研究下,也可以到安安DIY創作室博客一起討論一下。
JUnit-addons
對JUnit的一些補充,比如設置、獲取被測試對象的私有屬性的值,調用被測試對象的私有方法等。
常用類:junitx.util.PrivateAccessor
Spring 測試框架
可以測試基於Spring的應用,通過配置文件和註解自動組裝需要的單元測試對象。
提供了一些常用的J2EE Mock對象,比如HttpSession的Mock類等。
可以支持資料庫自動回滾,以防止對資料庫的單元測試(插入,刪除等)不可重復執行,防止修改資料庫狀態等。
DJUnit
通過代碼自動產生Mock對象,省去了自己手動編寫N多的Mock類。
此外,它的Eclipse插件還可以做到測試覆蓋率、分支統計。
EasyMock
功能同DJUnit,也是通過編程自動Mock掉與測試對象無關的類,方法。