本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html
喜歡的話麻煩點下Star哈java
文章首發於個人我的博客:python
www.how2playlife.comandroid
本文是微信公衆號【Java技術江湖】的《走進JavaWeb技術世界》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。git
該系列博文會告訴你如何從入門到進階,從servlet到框架,從ssm再到SpringBoot,一步步地學習JavaWeb基礎知識,並上手進行實戰,接着瞭解JavaWeb項目中常常要使用的技術和組件,包括日誌組件、Maven、Junit,等等內容,以便讓你更完整地瞭解整個JavaWeb技術體系,造成本身的知識框架。程序員
若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。github
文末贈送8000G的Java架構師學習資料,須要的朋友能夠到文末了解領取方式,資料包括Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源)面試
<!-- more -->數據庫
測試 在軟件開發中是一個很重要的方面,良好的測試能夠在很大程度決定一個應用的命運。 軟件測試中,主要有3大種類:
本文只對 單元測試 進行介紹,主要介紹如何在 Android Studio 下進行單元測試,單元測試使用的測試框架爲 JUnit
可能目前仍有很大一部分開發者未使用 單元測試 對他們的代碼進行測試,一方面多是以爲沒有必要,由於即便沒有進行單元測試,程序照樣運行得很好;另外一方面,也許有些人也認同單元測試的好處,可是因爲須要額外的學習成本,因此不少人也是沒有時間或者說是沒有耐心進行學習······ 這裏我想說的是,若是你們去看下 github 上目前主流的開源框架,star 數比較多的項目,通常都有很詳盡的測試用例。因此說,單元測試對於咱們的項目開發,仍是挺有好處的。 至於單元測試的好處,我這裏說起幾點:
本文實例講述了java單元測試JUnit框架原理與用法。分享給你們供你們參考,具體以下:
JUnit是一個Java語言的單元測試框架,它由 Kent Beck 和 Erich Gamma 創建,逐漸成爲 xUnit 家族中最爲成功的一個。
JUnit有它本身的JUnit擴展生態圈,多數Java的開發環境都已經集成了JUnit做爲單元測試的工具。在這裏,一個單元能夠是一個方法、類、包或者子系統。
所以,單元測試是指對代碼中的最小可測試單元進行檢查和驗證,以便確保它們正常工做。例如,咱們能夠給予必定的輸入測試輸出是不是所但願獲得的結果。在本篇博客中,做者將着重介紹 JUnit 4.X 版本的特性,這也是咱們在平常開發中使用最多的版本。
JUnit提供了註釋以及肯定的測試方法; JUnit提供了斷言用於測試預期的結果; JUnit測試優雅簡潔不須要花費太多的時間; JUnit測試讓你們能夠更快地編寫代碼而且提升質量; JUnit測試能夠組織成測試套件包含測試案例,甚至其餘測試套件; Junit顯示測試進度,若是測試是沒有問題條形是綠色的,測試失敗則會變成紅色; JUnit測試能夠自動運行,檢查本身的結果,並提供即時反饋,沒有必要經過測試結果報告來手動梳理。
@Test :該註釋表示,用其附着的公共無效方法(即用public修飾的void類型的方法 )能夠做爲一個測試用例;
@Before :該註釋表示,用其附着的方法必須在類中的每一個測試以前執行,以便執行測試某些必要的先決條件;
@BeforeClass :該註釋表示,用其附着的靜態方法必須執行一次並在類的全部測試以前,發生這種狀況時通常是測試計算共享配置方法,如鏈接到數據庫;
@After :該註釋表示,用其附着的方法在執行每項測試後執行,如執行每個測試後重置某些變量,刪除臨時變量等;
@AfterClass :該註釋表示,當須要執行全部的測試在JUnit測試用例類後執行,AfterClass註解可使用以清理創建方法,如斷開數據庫鏈接,注意:附有此批註(相似於BeforeClass)的方法必須定義爲靜態;
@Ignore :該註釋表示,當想暫時禁用特定的測試執行可使用忽略註釋,每一個被註解爲@Ignore的方法將不被執行。
/ * JUnit 註解示例 */ @Test public void testYeepay(){ Syetem.out.println("用@Test標示測試方法!"); } @AfterClass public static void paylus(){ Syetem.out.println("用@AfterClass標示的方法在測試用例類執行完以後!"); }
在這裏,做者將介紹一些斷言方法,全部這些方法都來自 org.junit.Assert 類,其擴展了 java.lang.Object 類併爲它們提供編寫測試,以便檢測故障。簡而言之,咱們就是經過斷言方法來判斷實際結果與咱們預期的結果是否相同,若是相同,則測試成功,反之,則測試失敗。
void assertEquals([String message], expected value, actual value) :斷言兩個值相等,值的類型能夠爲int、short、long、byte、char 或者 java.lang.Object,其中第一個參數是一個可選的字符串消息; void assertTrue([String message], boolean condition) :斷言一個條件爲真; void assertFalse([String message],boolean condition) :斷言一個條件爲假; void assertNotNull([String message], java.lang.Object object) :斷言一個對象不爲空(null); void assertNull([String message], java.lang.Object object) :斷言一個對象爲空(null); void assertSame([String message], java.lang.Object expected, java.lang.Object actual) :斷言兩個對象引用相同的對象; void assertNotSame([String message], java.lang.Object unexpected, java.lang.Object actual) :斷言兩個對象不是引用同一個對象; void assertArrayEquals([String message], expectedArray, resultArray) :斷言預期數組和結果數組相等,數組的類型能夠爲int、long、short、char、byte 或者 java.lang.Object
(1)使用 JUnit 3.X 版本進行單元測試時,測試類必需要繼承於 TestCase 父類; (2)測試方法須要遵循的原則:
① public的; ② void的; ③ 無方法參數; ④方法名稱必須以 test 開頭;
(3)不一樣的測試用例之間必定要保持徹底的獨立性,不能有任何的關聯;
(4)要掌握好測試方法的順序,不能依賴於測試方法本身的執行順序。
/ * 用 JUnit 3.X 進行測試 */ import junit.framework.Assert; import junit.framework.TestCase; public class TestOperation extends TestCase { private Operation operation; public TestOperation(String name) { // 構造函數 super(name); } @Override public void setUp() throws Exception { // 在每一個測試方法執行 [以前] 都會被調用,多用於初始化 System.out.println("歡迎使用Junit進行單元測試..."); operation = new Operation(); } @Override public void tearDown() throws Exception { // 在每一個測試方法執行 [以後] 都會被調用,多用於釋放資源 System.out.println("Junit單元測試結束..."); } public void testDivideByZero() { Throwable te = null; try { operation.divide(6, 0); Assert.fail("測試失敗"); //斷言失敗 } catch (Exception e) { e.printStackTrace(); te = e; } Assert.assertEquals(Exception.class, te.getClass()); Assert.assertEquals("除數不能爲 0 ", te.getMessage()); } }
(1)使用 JUnit 4.X 版本進行單元測試時,不用測試類繼承TestCase父類; (2)JUnit 4.X 版本,引用了註解的方式進行單元測試; (3)JUnit 4.X 版本咱們經常使用的註解包括:
@Before 註解:與JUnit 3.X 中的 setUp() 方法功能同樣,在每一個測試方法以前執行,多用於初始化;
@After 註解:與 JUnit 3.X 中的 tearDown() 方法功能同樣,在每一個測試方法以後執行,多用於釋放資源;
@Test(timeout = xxx) 註解:設置當前測試方法在必定時間內運行完,不然返回錯誤;
@Test(expected = Exception.class) 註解:設置被測試的方法是否有異常拋出。拋出異常類型爲:Exception.class;
此外,咱們能夠經過閱讀上面的第二部分「2 註解」瞭解更多的註解。
/ * 用 JUnit 4.X 進行測試 */ 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 TestOperation { private Operation operation; @BeforeClass public static void globalInit() { // 在全部方法執行以前執行 System.out.println("@BeforeClass標註的方法,在全部方法執行以前執行..."); } @AfterClass public static void globalDestory() { // 在全部方法執行以後執行 System.out.println("@AfterClass標註的方法,在全部方法執行以後執行..."); } @Before public void setUp() { // 在每一個測試方法以前執行 System.out.println("@Before標註的方法,在每一個測試方法以前執行..."); operation = new Operation(); } @After public void tearDown() { // 在每一個測試方法以後執行 System.out.println("@After標註的方法,在每一個測試方法以後執行..."); } @Test(timeout=600) public void testAdd() { // 設置限定測試方法的運行時間 若是超出則返回錯誤 System.out.println("測試 add 方法..."); int result = operation.add(2, 3); assertEquals(5, result); } @Test public void testSubtract() { System.out.println("測試 subtract 方法..."); int result = operation.subtract(1, 2); assertEquals(-1, result); } @Test public void testMultiply() { System.out.println("測試 multiply 方法..."); int result = operation.multiply(2, 3); assertEquals(6, result); } @Test public void testDivide() { System.out.println("測試 divide 方法..."); int result = 0; try { result = operation.divide(6, 2); } catch (Exception e) { fail(); } assertEquals(3, result); } @Test(expected = Exception.class) public void testDivideAgain() throws Exception { System.out.println("測試 divide 方法,除數爲 0 的狀況..."); operation.divide(6, 0); fail("test Error"); } public static void main(String[] args) { } }
經過以上兩個例子,咱們已經能夠大體知道 JUnit 3.X 和 JUnit 4.X 兩個版本的區別啦!
首先,若是咱們使用 JUnit 3.X,那麼在咱們寫的測試類的時候,必定要繼承 TestCase 類,可是若是咱們使用 JUnit 4.X,則不需繼承 TestCase 類,直接使用註解就能夠啦!
在 JUnit 3.X 中,還強制要求測試方法的命名爲「 testXxxx 」這種格式;
在 JUnit 4.X 中,則不要求測試方法的命名格式,但做者仍是建議測試方法統一命名爲「 testXxxx 」這種格式,簡潔明瞭。
此外,在上面的兩個示例中,咱們只給出了測試類,可是在這以前,還應該有一個被測試類,也就是咱們真正要實現功能的類。如今,做者將給出上面示例中被測試的類,即 Operation 類:
/ * 定義了加減乘除的法則 */ public class Operation { public static void main(String[] args) { System.out.println("a + b = " + add(1,2)); System.out.println("a - b = " + subtract(1,2)); System.out.println("a * b = " + multiply(1,2)); System.out.println("a / b = " + divide(4,2)); System.out.println("a / b = " + divide(1,0)); } public static int add(int a, int b) { return a + b; } public static int subtract(int a, int b) { return a - b; } public static int multiply(int a, int b) { return a * b; } public static int divide(int a, int b) { return a / b; } }
import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.util.ArrayList; import java.util.Collection; / * 一、建立一個測試類,繼承TestCase類 */ public class SimpleTestDemo extends TestCase { public SimpleTestDemo(String name) { super(name); } / * 二、寫一個測試方法,斷言指望的結果 */ public void testEmptyCollection(){ Collection collection = new ArrayList(); assertTrue(collection.isEmpty()); } / * 三、寫一個suite()方法,它會使用反射動態的建立一個包含全部的testXxxx方法的測試套件 */ public static Test suit(){ return new TestSuite(SimpleTestDemo.class); } / * 四、寫一個main()方法,以文本運行器的方式方便的運行測試 */ public static void main(String[] args) { junit.textui.TestRunner.run(suit()); } }
有些童鞋可能會有一些誤解,認爲寫測試代碼沒有用,並且還會增大本身的壓力,浪費時間。但事實上,寫測試代碼與否,仍是有很大區別的,若是是在小的項目中,或許這種區別還不太明顯,但若是在大型項目中,一旦出現錯誤或異常,用人力去排查的話,那將會浪費不少時間,並且還不必定排查的出來,可是若是用測試代碼的話,JUnit 就是自動幫咱們判斷一些代碼的結果正確與否,從而節省的時間將會遠遠超過你寫測試代碼的時間。
所以,我的建議:要養成編寫測試代碼的習慣,碼一點、測一點;再碼一點,再測一點,如此循環。在咱們不斷編寫與測試代碼的過程當中,咱們將會對類的行爲有一個更爲深刻的瞭解,從而能夠有效的提升咱們的工做效率。下面,做者就給出一些具體的編寫測試代碼的技巧和較好的實踐方法:
1. 不要用 TestCase 的構造函數初始化 Fixture,而要用 setUp() 和 tearDown() 方法; 2. 不要依賴或假定測試運行的順序,由於 JUnit 會利用 Vector 保存測試方法,因此不一樣的平臺會按不一樣的順序從 Vector 中取出測試方法; 3. 避免編寫有反作用的 TestCase,例如:若是隨後的測試依賴於某些特定的交易數據,就不要提交交易數據,只須要簡單的回滾就能夠了; 4. 當繼承一個測試類時,記得調用父類的 setUp() 和 tearDown() 方法; 5. 將測試代碼和工做代碼放在一塊兒,同步編譯和更新; 6. 測試類和測試方法應該有一致的命名方案,如在工做類名前加上 test 從而造成測試類名; 7. 確保測試與時間無關,不要使用過時的數據進行測試,以致於致使在隨後的維護過程當中很難重現測試; 8. 若是編寫的軟件面向國際市場,那麼編寫測試時必定要考慮國際化的因素; 9. 儘量地利用 JUnit 提供地 assert 和 fail 方法以及異常處理的方法,其可使代碼更爲簡潔; 10. 測試要儘量地小,執行速度快; 11. 不要硬性規定數據文件的路徑; 12. 使用文檔生成器作測試文檔。
1.Arquillian
Arquillian是一個基於JVM的高度可擴展的測試平臺,容許開發人員建立Java的自動化集成,功能和驗收測試。Arquillian容許你在運行態時執行測試。Arquillian可用於管理容器(或容器)的生命週期,綁定測試用例,依賴類和資源。它還可以將壓縮包部署到容器中,並在容器中執行測試並捕獲結果並建立報告。
Arquillian集成了熟悉的測試框架,如JUnit 四、TestNG 5,並容許使用現有的IDE啓動測試。而且因爲其模塊化設計,它可以運行Ant和Maven測試插件。Arquillian目的是簡化項目集成測試和功能測試的編寫,讓它們能像單元測試同樣簡單。
2.JTEST
JTest也被稱爲「Parasoft JTest」,是Parasoft公司生產的自動化Java軟件測試和靜態分析軟件。 JTest包括用於單元測試用例生成和執行,靜態代碼分析,數據流靜態分析和度量分析,迴歸測試,運行時錯誤檢測的功能。
還能夠進行結對的代碼審查流程自動化和運行時錯誤檢測,例如:條件,異常,資源和內存泄漏,安全攻擊漏洞等。
3.The Grinder
「The Grinder」是一個Java負載測試框架。而且經過使用大量負載注射器來爲分佈式測試提供便利。Grinder能夠對具備Java API的任何內容加載測試。這包括HTTP Web服務器,SOAP、REST Web服務、應用程序服務器,包括自定義協議。測試腳本用強大的Jython和Clojure語言編寫。Grinder的GUI控制檯容許對多個負載注射器進行監控和控制,並自動管理客戶端鏈接和Cookie,SSL,代理感知和鏈接限制。您能夠在這裏找到關於磨牀功能的更多深刻信息。
4.TestNG
TestNG受JUnit和NUnit的啓發,是爲Java編程語言而設計的測試框架。TestNG主要設計用於覆蓋更普遍的測試類別,如單元,功能,端到端,集成等。它還引入了一些新功能,使其更強大,更易於使用,如:註解,運行在大線程池中進行各類策略測試,多線程安全驗證代碼測試,靈活的測試配置,數據驅動的參數測試支持等等。
TestNG有各類工具和插件(如Eclipse,IDEA,Maven等)支持。
5.JUnit
JUnit是爲Java編程語言設計的單元測試框架。JUnit在測試驅動開發框架的開發中發揮了重要做用。它是單元測試框架之一,統稱爲由SUnit起源的xUnit。
6.JWalk
JWalk被設計爲用於Java編程語言的單元測試工具包。它被設計爲支持稱爲「Lazy系統單元測試」的測試範例。
JWalkTester工具對任何由程序員提供的編譯的Java類執行任何測試。它可以經過靜態和動態分析以及來自程序員的提示來測試懶惰Lazy規範的一致性。
7.Mockito
Mockito被設計爲用於Java的開源測試框架,MIT許可證。Mockito容許程序員爲了測試驅動開發(TDD)或行爲驅動開發(BDD)而在自動化單元測試中建立和測試雙對象(Mock對象)。
8 Powermock
PowerMock是用於對源代碼進行單元測試的Java框架,它能夠做爲其餘模擬框架的擴展,好比原型Mockito或EasyMock,但具備更強大的功能。PowerMock利用自定義的類加載器和字節碼操縱器來實現靜態方法,構造函數,最終類和方法以及私有方法等的模擬。它主要是爲了擴展示有的API,使用少許的方法和註解來實現額外的功能。
https://www.jianshu.com/p/0530cb31c3b2 https://blog.csdn.net/Dream_Weave/article/details/83859750 https://blog.csdn.net/qq_26295547/article/details/83145642 https://www.jianshu.com/p/0530cb31c3b2 http://www.sohu.com/a/145107423_731023
黃小斜是跨考軟件工程的 985 碩士,自學 Java 兩年,拿到了 BAT 等近十家大廠 offer,從技術小白成長爲阿里工程師。
做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得和程序人生,目前黃小斜的CSDN博客有百萬+訪問量,知乎粉絲2W+,全網已有10W+讀者。
黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!
原創電子書: 關注微信公衆號【黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】
這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
(關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源)
Java工程師必備學習資源: 一些Java工程師經常使用學習資源,關注公衆號後,後臺回覆關鍵字 「Java」 便可免費無套路獲取。