推薦JUnit視頻教程:JUnit—Java單元測試必備工具。html
單元測試又稱模塊測試,屬於白盒測試,是最小單位的測試。模塊分爲程序模塊和功能模塊。功能模塊指實現了一個完整功能的模塊(單元),一個完整的程序單元具有輸入、加工和輸出三個環節。並且每一個程序單元都應該有正規的規格說明,使之對其輸入、加工和輸出的關係作出名明確的描述。java
JUnit是一個迴歸測試框架(regression testing framework)。Junit測試是程序員測試,即所謂白盒測試,由於程序員知道被測試的軟件如何(How)完成功能和完成什麼樣(What)的功能。Junit是一套框架,繼承TestCase類,就能夠用Junit進行自動測試了。git
①JUnit是用於編寫可複用測試集的簡單框架,是xUnit的一個子集。xUnit是一套基於測試驅動開發的測試框架,有PythonUnit、CppUnit、JUnit等。程序員
②Junit測試是程序員測試,即所謂白盒測試,由於程序員知道被測試的軟件如何(How)完成功能和完成什麼樣(What)的功能。編程
③多數Java的開發環境都已經集成了JUnit做爲單元測試的工具,好比IDEA,Eclipse等等。框架
④JUnit官網:Junitmaven
①測試框架能夠幫助咱們對編寫的程序進行有目的地測試,幫助咱們最大限度地避免代碼中的bug,以保證系統的正確性和穩定性。編程語言
②不少人對本身寫的代碼,測試時就簡單寫main,而後sysout輸出控制檯觀察結果。這樣很是枯燥繁瑣,不規範。缺點:測試方法不能一塊兒運行,測試結果要程序猿本身觀察才能夠判斷程序邏輯是否正確。編輯器
③JUnit的斷言機制,能夠直接將咱們的預期結果和程序運行的結果進行一個比對,確保對結果的可預知性。ide
評測測試過程當中已經執行的代碼的多少。
代碼的覆蓋程度,一種度量方式。針對代碼的測試覆蓋率有許多種度量方式。
語句覆蓋( StatementCoverage ):也稱爲行覆蓋( lin EC overage ) , 段覆蓋(segmentcoverage)和基本塊覆蓋(bASicblockcoverage)。它度量每個可執行語句是否被執行到了。
斷定覆蓋(DecisionCoverage):也被稱爲分支覆蓋(branchcoverage),全部邊界覆蓋(alledgescoverage), 基本路徑覆蓋( basispathcoverage ), 斷定路徑覆蓋(decisiondecisionpath或DDPtesting)。它度量是否每一個 BOOL 型的表達式取值true 和 false 在控制結構中都被測試到了。
條件覆蓋(ConDItionCoverage): 它獨立的度量每個子表達式,報告每個子表達式的結果的 true 或 false。這個度量和斷定覆蓋(decisioncoverage)類似,可是對控制流更敏感。不過,徹底的條件覆蓋並不能保證徹底的斷定覆蓋。
路徑覆蓋(PathCoverage):也稱爲斷言覆蓋(prEDIcatecoverage),它度量了是否函數的每個可能的分支都被執行了。路徑覆蓋的一個好處是:須要完全的測試。但有兩個缺點:一是,路徑是以分支的指數級別增長的,例如:一個函數包含 10個 IF 語句,就有 1024 個路徑要測試。若是加入一個 IF 語句,路徑數就達到 2048;二是,許多路徑不可能與執行的數據無關。
- 循環覆蓋(LOOPCoverage):這個度量報告你是否執行了每一個循環體零次、只有一次仍是多餘一次(連續地)。對於 dowhile循環,循環覆蓋報告你是否執行了每一個循環體只有一次仍是多餘一次(連續地)。這個度量的有價值的方面是肯定是否對於 while 循環和 for 循環執行了多於一次,這個信息在其它的覆蓋率報告中是沒有的。
IDEA中自帶JUnit的jar包(hamcrest-core-1.3.jar
,junit.jar
,junit-4.12.jar
):位於安裝目錄下的lib文件內。即:IntelliJ IDEA 2018.1\lib
IDEA自帶一個JUnit插件, 該插件能夠運行JUnit測試文件,但沒法自動生成JUnit測試代碼. 若是須要自動生成測試代碼,須要安裝JUnitGenerator V2.0
插件。
安裝方法:File
-->settings
-->Plguins
-->Browse repositories
-->輸入JUnit
-->選擇JUnit Generator V2.0
安裝,安裝好後重啓 IDEA,便可使用。
PS: IDEA自帶的JUnit插件和JUnitGeneratorV2.0插件都要勾選上,若只勾選JUnit可能致使沒法自動生成測試文件,若只勾選JUnitGenerator V2.0可能致使生成的測試文件沒法運行
經過模版生成的測試代碼與java類在同一個目錄下,與maven項目標準測試目錄不匹配。修改方法:
${SOURCEPATH}/test/${PACKAGE}/${FILENAME}
修改成${SOURCEPATH}/../test/java/${PACKAGE}/${FILENAME}
有時候會出現一個提示框,提示選擇(general/merge/exixt),選擇general就行
${SOURCEPATH}
原類的路徑,就是你本身寫的類
${PACKAGE}
原類的包名,java包命名規範就是按照包名一級一級建立的文件夾
${filename}
測試類的類名
修改 Junit4 選項卡中包的申明,把默認的 test 前綴去掉。
生成的測試文件@since位置Date可能存在亂碼,可配置JUnit模板更改日期格式,不影響程序可直接忽略。修改方法:
第40行:@since <pre>$Date</pre>
修改成
@since <pre>$today</pre>
在婁老師的博客文章中講了單元測試,咱們根據老師的方法來進行簡單入門單元測試。
什麼是單元測試?單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。對於單元測試中單元的含義,通常來講,要根據實際狀況去斷定其具體含義,如Java裏單元指一個類。
編程是智力活動,不是打字,編程前要把幹什麼、如何幹想清楚才能把程序寫對、寫好。與目前很多同窗一說編程就打開編輯器寫代碼不一樣,我但願同窗們養成一個習慣,當大家想用程序解決問題時,要會寫三種碼:
- 僞代碼
- 產品代碼
- 測試代碼
僞代碼與具體編程語言無關,不要寫與具體編程語言語法相關的語句(如
用malloc分配內存
,這樣只能用C語言編程了),僞代碼
從意圖層面來解決問題,最終,僞代碼
是產品代碼
最天然的、最好的註釋。
需求:咱們要在一個Calculator
類中來實現簡單計算器的功能。
設計的僞代碼:
簡單計算器: 加法:返回兩個數相加後的結果 減法:返回兩個數相減後的結果 乘法:返回兩個數相乘後的結果 除法:除數不爲0,返回兩個數相除後的結果 除數爲0,打印異常信息在程序中出錯的位置及緣由 其餘 :未完成的模塊例如平方、開方等等
有了僞代碼
,用特定語言翻譯一下,就是可用的產品代碼
了。
翻譯以後的產品代碼Calculator.java
:
public class Calculator { public int add(int x, int y) { //加法 return x + y; } public int sub(int x, int y) { //減法 return x - y; } public int mul(int x, int y) { //乘法 return x * y; } public int div(int x, int y) { //除法 return x / y; } public int div2(int x, int y) { //除法 作了異常判斷 try { int z = x / y; } catch (Exception e) { e.printStackTrace(); } return x / y; } public void loop(int x, int y) { //死循環 for (; ; ) x = y; } public void unCompleted(int x, int y) { //未完成的模塊:例如平方、開方等等 //還在開發中 } // public static void main(String[] args) { // 傳統代碼測試 // int a = 8; // int b = 2; // Calculator calculator = new Calculator(); // System.out.println(calculator.add(a, b)); // System.out.println(calculator.sub(a, b)); // System.out.println(calculator.mul(a, b)); // System.out.println(calculator.div(a, b)); // System.out.println(calculator.div2(a,0)); // } }
在IDEA中建立項目unitTask01
,在src
右鍵新建java類com.ryanjie.junit01.Calculator
,將上述代碼寫入。
寫了產品代碼,咱們還要寫測試代碼,證實本身的代碼沒有問題。
Java編程時,程序員對類實現的測試叫單元測試。類XXXX的單元測試,咱們通常寫建一個XXXXTest的類。
因此,對於Calculator類
,咱們寫一個CalculatorTest.java
的測試模塊,代碼以下:
public class CalculatorTest { public static void main(String[] args) { Calculator calculator = new Calculator(); if (calculator.add(8, 2) == 10) { System.out.println("Test passed!"); } else { System.out.println("Test failed!"); } if (calculator.sub(8, 2) == 6) { System.out.println("Test passed!"); } else { System.out.println("Test failed!"); } if (calculator.mul(8, 2) == 16) { System.out.println("Test passed!"); } else { System.out.println("Test failed!"); } if (calculator.div(8, 2) == 4) { System.out.println("Test passed!"); } else { System.out.println("Test failed!"); } } }
這裏咱們設計了一個測試用例(Test Case)
,測試用例是爲某個特殊目標而編制的一組測試輸入、執行條件以及預期結果,以便測試某個程序路徑或覈實是否知足某個特定需求。這裏咱們的測試輸入8和2的加減乘除四種運算
,預期結果分別爲10,6,16,4
。
咱們在Calculator
類上單擊鼠標右鍵,在彈出的菜單中選擇Generate
(咱們能夠看到對應鍵盤快捷鍵爲Alt+Insert
)-> Junit Test
-> Junit 4
,這時IDEA會自動生成一個test目錄並生成CalculatorTest類,咱們先刪除自動生成的代碼,輸入剛纔寫的CalculatorTest.java
代碼。
在 IDEA中咱們把產品代碼放在src
目錄中,把測試代碼放在test
目錄中,在命令行中咱們知道要設置SOURCEPATH環境變量,在IDEA中咱們右鍵單擊test
目錄,在彈出的菜單中選擇Mark Directory as
->Test Sources Root
就能夠了:(這時test文件夾圖標會變綠)
在IDEA中運行結果以下,測試結果符合預期:
在剛纔自動生成的test
目錄下,CalculatorTest.java
裏代碼以下:
public class CalculatorTest { @Before public void before() throws Exception { } @After public void after() throws Exception { } /** * * Method: add(int x, int y) * */ @Test public void testAdd() throws Exception { } /** * * Method: sub(int x, int y) * */ @Test public void testSub() throws Exception { } /** * * Method: mul(int x, int y) * */ @Test public void testMul() throws Exception { } /** * * Method: div(int x, int y) * */ @Test public void testDiv() throws Exception { } /** * * Method: div2(int x, int y) * */ @Test public void testDiv2() throws Exception { } /** * * Method: loop(int x, int y) * */ @Test public void testLoop() throws Exception { } /** * * Method: unCompleted(int x, int y) * */ @Test public void testUnCompleted() throws Exception { } }
咱們修改CalculatorTest.java
測試模塊,代碼以下:
public class CalculatorTest { Calculator calculator; @Before public void setUp() throws Exception { calculator = new Calculator(); } @After public void after() throws Exception { } /** * * Method: add(int x, int y) * */ @Test public void testAdd() throws Exception { Assert.assertEquals(calculator.add(8,2),10); } /** * * Method: sub(int x, int y) * */ @Test public void testSub() throws Exception { Assert.assertEquals(calculator.sub(8,2),6); } /** * * Method: mul(int x, int y) * */ @Test public void testMul() throws Exception { Assert.assertEquals(calculator.mul(8,2),16); } /** * * Method: div(int x, int y) * */ @Test public void testDiv() throws Exception { Assert.assertEquals(calculator.div(8,2),4); } /** * * Method: div2(int x, int y) * */ @Ignore public void testDiv2() throws Exception { } /** * * Method: loop(int x, int y) * */ @Ignore public void testLoop() throws Exception { } /** * * Method: unCompleted(int x, int y) * */ @Ignore public void testUnCompleted() throws Exception { } }
在IDEA中運行結果以下,測試結果符合預期:
咱們能夠經過Run
->Edit Configuration
或工具欄上的標籤來調整咱們測試運行配置:
在Configuration
選項卡,用戶能夠選擇須要運行的測試。例如,您能夠從一個類、程序包、測試套件或甚至模式中運行全部的測試。這裏的Fork模式讓用戶在一個單獨的進程運行每一個測試。
代碼覆蓋測試:
過Run
->Run 'MyClassTest' with Coverage
或工具欄上的選項運行特定模式的測試。
當覆蓋模式運行至少一個測試以後,IDE將會在Project工具窗口顯示每一個程序包、類的覆蓋率數據,同時在Coverage工具窗和編輯器中也會顯示。
若是用戶添加另外一個方法到junit01
,並運行覆蓋率測junit01
,就會發現,沒有被測試覆蓋到的代碼都將高亮顯示爲紅色。覆蓋的代碼顏色則是綠色。若是一些代碼是隻覆蓋部分,那沒將顯示爲黃色。
本文代碼:UnitTask01