本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html
https://github.com/h2pl/Java-Tutorial前端
喜歡的話麻煩點下Star哈java
文章首發於個人我的博客:python
www.how2playlife.comandroid
本文是微信公衆號【Java技術江湖】的《走進JavaWeb技術世界》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。git
該系列博文會告訴你如何從入門到進階,從servlet到框架,從ssm再到SpringBoot,一步步地學習JavaWeb基礎知識,並上手進行實戰,接着瞭解JavaWeb項目中常常要使用的技術和組件,包括日誌組件、Maven、Junit,等等內容,以便讓你更完整地瞭解整個JavaWeb技術體系,造成本身的知識框架。程序員
若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。github
文末贈送8000G的Java架構師學習資料,須要的朋友能夠到文末了解領取方式,資料包括Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源) 面試
測試 在軟件開發中是一個很重要的方面,良好的測試能夠在很大程度決定一個應用的命運。軟件測試中,主要有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,使用少許的方法和註解來實現額外的功能。
黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!
原創電子書:關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】
這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
Java工程師必備學習資源:關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源
黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!
原創電子書:關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】
這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
Java工程師必備學習資源:關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源