JAVA     Junit4   測試框架

序言

剛學Java的時候就聽說過JUnit了,單元測試框架,很好用的測試框架,JUnit測試框架將測試更加便捷和容易,編寫測試程式碼也是簡單、明瞭,功能強大。今天我給大家簡單分享一下最新JUnit4的使用,幾分鐘入門!

匯入jar包

在整合開發環境中匯入相應jar包:junit-4.12.jar、hamcrest-core-1.3.rc2.jar、hamcrest-library-1.3.rc2.jar。如果只匯入第一個jar的話就不能啟動測試程式會報錯,報錯及幾個包的關係詳見我的部落格:JUnit4單元測試報錯。在此,給大家提供一下這幾個jar包的免費下載連結:

junit-4.12.jar下載

hamcrest-library-1.3.rc2.jar下載

hamcrest-core-1.3.rc2.jar下載

匯入方法看如下截圖就明白了:

 

新建測試用例

右擊包名,點選新建,或者新建裡的others,選擇JUnit test case,如下圖所示:

 

接下來,給測試類起名字和選擇要測試的類,如下圖所示:

 

然後點選【Next】,選擇要被測試類中的測試方法,如下圖所示:

最後新建完成,如下(第一個方法是生成的方法,後邊幾個都是我自己手動寫上去的):

  1. package JUnitTest;
  2. import static org.junit.Assert.*;
  3. import org.junit.After;
  4. import org.junit.AfterClass;
  5. import org.junit.Before;
  6. import org.junit.BeforeClass;
  7. import org.junit.Ignore;
  8. import org.junit.Test;
  9. public class TestJava {
  10. @Test
  11. public void testMain() {
  12. fail("Not yet implemented");
  13. }
  14. @Test
  15. public void testTest() {
  16. System.out.println("@Test");//呼叫自己要測試的方法
  17. }
  18. @Test
  19. public void testAssert() {
  20. assertEquals("chenleixing","chenlei");
  21. }
  22. @Test(timeout=1)
  23. public void testTimeout() {
  24. System.out.println("超時測試");
  25. }
  26. @Before
  27. public void testBefore(){
  28. System.out.println("@Before");
  29. }
  30. @BeforeClass
  31. public static void testBeforeClass(){//必須為靜態方法
  32. System.out.println("@BeforeClass");
  33. }
  34. @After
  35. public void testAfter(){
  36. System.out.println("@After");
  37. }
  38. @AfterClass
  39. public static void testAfterClass(){//必須為靜態方法
  40. System.out.println("@AfterClass");
  41. }
  42. @Ignore
  43. public void testIgnore(){
  44. System.out.println("@Ignore");
  45. }
  46. }

JUnit4註解解釋

1. @Test : 測試方法,測試程式會執行的方法,後邊可以跟引數代表不同的測試,如(expected=XXException.class) 異常測試,(timeout=xxx)超時測試
2. @Ignore : 被忽略的測試方法
3. @Before: 每一個測試方法之前執行
4. @After : 每一個測試方法之後執行
5. @BeforeClass: 所有測試開始之前執行
6. @AfterClass: 所有測試結束之後執行
fail方法是指測試失敗

assertEquals測試2個引數是否相等,具體參考相應API

更多方法可參考相應API文件(博文末尾分享下載連線給大家)

執行測試用例

把自己的測試程式碼寫在@Test註解後者其他註解的方法裡邊,點選執行新建的測試用例,結果如下:

 

帶差號的是說明測試失敗的,testMain()和testAssert()肯定會失敗,對號的是測試成功的。

控制檯輸出的結果如下:

  1. <span style="font-size:18px;">@BeforeClass
  2. @Before
  3. 超時測試
  4. @After
  5. @Before
  6. @After
  7. @Before
  8. @Test
  9. @After
  10. @Before
  11. @After
  12. @AfterClass</span>

免費下載jar包和文件

junit-4.12.jar下載

hamcrest-library-1.3.rc2.jar下載

hamcrest-core-1.3.rc2.jar下載

junit4API.chm.html下載

JUnit4高階篇及更加的詳細深入的使用,請參考:JUnit4高階篇-由淺入深。

第一步:

開啟eclipse.exe,建立一個名為“Ives”的工專案,建立一個名為”UnitTest”的類。寫幾個方法:兩數+ - * /的方法和返回結果的方法。

程式碼如下:

 1 import java.util.*;
2 public class Expression {
3 int a;
4 int b;
5 static int c;//使用者答案
6 int answer;//答案
7 static Scanner in=new Scanner(System.in);
8
9
10 public int Expression(){
11 a = new Random().nextInt()%10;
12 b = new Random().nextInt()%10;
13 System.out.print(""+a+"+"+b+"=");
14 return answer = a + b;
15
16 }
17 public static void main(String[] args){
18 int answer;
19 Expression expression = new Expression();
20 answer = expression.Expression();
21 try{
22 Expression.c = in.nextInt();
23 }
24 catch(InputMismatchException e)
25 { System.err.println("\nError ,please Enter a Int number");
26 }
27 if(answer==c)
28 {
29 System.out.print("答對了");
30 }
31 else System.out.print("答錯了");
32 //System.out.print("answer="+answer);
33 }
34 }

第二步:

Duang!酷炫的效果來了,跟緊腳步了。

將 JUnit4 單元測試包引入這個專案:在該專案“Ives”上點右鍵,點“屬性”(Pr o perties),如圖:

在彈出的屬性視窗中,首先在左邊選擇“Java 構建路徑 ” (Java Build Path) , 然後到右上選擇"庫(L)"( Libraries )標籤,之後在最右邊點選“新增庫(A) ”(Add Libraries) 按鈕,如下圖所示:

點選完成, JUnit4 軟體包就被包含進我們這個專案了。

第三步:

生成 JUnit 測試框架:在 Eclipse 的包資源管理器( Package Explorer) 中用右鍵點選該類”UnitTest“彈出選單,選擇 新建 →JUnit測試用例 ( New à JUnit Test Case )。如下圖所示:

在彈出的對話方塊中,進行相應的選擇,如下圖所示:

點選完成之後會出現如下圖:

千萬不要去刪除@Test這個標誌很重要的!!!!!然後把fail(“尚未實現”)刪除,把自己的程式碼敲進去就可以了。我選擇了測試4個方法,所以它會自動生成4個測試方法。

Duang!!!

那測試方法怎麼寫呢?舉個例子,我想知道我的UnitTest裡面的plus方法有沒有寫對,那我就對這個方法寫個測試。把a,b兩個數傳遞進去,例如a=1和b=1,那a+b就等2,所以這裡我們又要了解新的東西了。那就是關於JUnit
的api了,下面有關於JUnit的api,到時候我看看要不要貼幾個常用的方法出來,加上例項,這樣會更加容易理解。

繼續我們的話題:我們知道a+b=2,所以如果plus方法的result是2的話,那就說明了我們的這個plus暫時沒有這型別的bug。所以我們要用到方法 assertEquals(double expected, double actual) 這個方法裡的double expected是我們期望的值,double actual是實際的值。例如assertEquals(2, a+b),這樣就可以測試方法有沒有算錯了。其實電腦一般都不會算錯吧?哈哈

完整的測試程式碼如下:

 1 import static org.junit.Assert.*;
2 import org.junit.Test;
3
4 public class UnitTestTest {
5 public static UnitTest puls = new UnitTest();
6 public static int answer;
7 @Test
8 public void testPlus() {
9 puls.plus(1,1);
10 assertEquals(2, puls.getresult());
11 }
12
13 @Test
14 public void testMinus() {
15 puls.minus(1,1);
16 assertEquals(0, puls.getresult());
17 }
18
19 @Test
20 public void testMultiply() {
21 puls.multiply(1,1);
22 assertEquals(1, puls.getresult());
23
24 }
25
26 @Test(expected=ArithmeticException.class)
27 public void testDivide1(){
28 puls.divide(0, 1);
29 }
30
31 @Test
32 public void testDivide() {
33 puls.divide(1,1);
34 assertEquals(1, puls.getresult());
35 }
36 }

可能用心看的童鞋可能會發現我還寫了一個測試時關於有沒有丟擲異常的。如果除數為0那就丟擲異常,再去測試它除數為0是有沒有丟擲異常。有人可能會問,我不知道什麼異常啊,很簡單,看

我們寫完程式碼,那麼唰唰唰的快感馬上就要到來了。

我把minus方法裡的“減號”改成了“加號”:如下圖

然後在執行測試類UnitTestTest.如下圖:

被測試的程式碼有bug,也就是之前把-修改成了+,所以就會出故障。

所以當全部都是綠色的時候是不是很爽,有沒有感受到割草機(JUnit4)的唰唰唰的快感。

接下來介紹一下什麼是JUnit?

Junit最初是由Erich Gamma和Kent Beck編寫的一個迴歸測試框架(regression testing framework),為單元測試(Unit Test)的支援框架,用來編寫和執行重覆性的測試,即所謂白盒測試,Junit是一套框架,繼承TestCase類,就可以用Junit進行自動測試了

Junit的簡單的環境配置:

在Eclipse中選擇專案Junit4(在Package Explorer中)—>右擊滑鼠—>選擇properties—>選擇JavaBuild Path(在左邊的選單中)—>在右邊選標籤 Libraries->單擊按鈕“Add Library”—>選JUnit,單擊“Next>”—>選擇JUnit library version為:JUnit4—>單擊按鈕“Finish”––>單擊按鈕“OK”

JUnit4的基礎知識介紹

JUnit4的常用註解:

@Test:測試方法,測試程式會執行的方法,後邊可以跟引數代表不同的測試,如(expected=XXException.class)異常測試,(timeout=xxx(毫秒))超時測試
@BeforeClass:它會在所有的方法執行前被執行,static修飾
@AfterClass:它會在所有的方法執行結束後被執行,static修飾
@Before:會在每一個測試方法被執行前執行一次,初始化方法
@After:會在每一個測試方法執行後被執行一次,釋放資源
@Ignore:所修飾的測試方法會被測試執行器忽略
@RunWith:可以更改測試執行器,可以自己設定執行器,只需要繼承org.junit.runner.Runner這個類就行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

JUnit4的常用方法:

fail()方法:是指測試失敗
assertEquals()方法:測試2個引數(一個是預期值,一個是實際值)是否相等
  • 1
  • 2
  • 1
  • 2

其他方法看這篇文件:(線上文件-junit-4.10):http://tool.oschina.net/apidocs/apidoc?api=junit-4.10

JUnit4的執行流程介紹:

1.@BeforeClass修飾的方法會在所有方法被呼叫前被執行,而且該方法是靜態的,所以當測試類被載入後接著就會執行它,而且在記憶體中它只會存在一份例項,它比較適合載入配置檔案,進行初始化等等

2.@Before和@After會在每個測試方法的前後各執行一次

3.@AfterClass所修飾的方法會在所有方法被呼叫後被執行,通常用來對資源的清理,如關閉資料庫的連線

JUnit4的基本使用介紹

在寫測試程式碼時這裡有幾點值得注意:

1.測試方法上必須使用@Test進行修飾
2.測試方法必須使用public void修飾,不帶任何引數
3.新建一個原始碼目錄(如test)來存放我們的測試程式碼
4.測試類的包應該和被測試類保持一致
5.建議測試類使用Test作為類名的字尾,測試方法使用test作為方法名的字首
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

JUnit4之超時測試的使用:

通過@Test 註解中,為timeout引數指定時間值,即可進行超時測試,如果測試執行時間超過指定的毫秒數,測試失敗,超時測試對網路連結類非常重要,通過timeout 進行超時測試非常簡單

@Test(timeout=2000) //2000ms
public void testWhile(){
while(true){
System.out.println("run....");
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

JUnit4之異常測試的使用:

在進行單元測試的時候有的時候需要測試某一方法是否丟擲了正確的異常,我們希望在單元測試中通過測試保證該方法會正確的丟擲正確型別的異常

@Test(excepted=ArithmeticException.class)
public void testDivide(){
c.divide(2/0);
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

JUnit4測試套件的介紹和使用:

在介紹之前首先我們來看看@RunWith:

當類被@RunWith註解修飾,或者類繼承了一個被該註解修飾的類.JUnit將會使用這個註解所指明的執行器(runner)來執行測試,而不是JUnit預設的執行器

JUnit測試套件的使用,即批量執行測試類,以及JUnit中的引數化設定,接下來舉例使用:

1.首先是新建兩個測試任務類:

public class TaskTest1{
@Test
public void test(){
System.out.println("this is TaskTest1...");
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
public class TaskTest2{
@Test
public void test() {
System.out.println("this is TaskTest2...");
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.最後是新建一個套件類,包含以上兩個任務類:

@RunWith(Suite.class)
@Suite.SuiteClasses({TaskTest1.class,TaskTest2.class,TaskTest3.class})
public class SuiteTest {
/*
* 1.測試套件就是組織測試類一起執行的
* 2.寫一個作為測試套件的入口類,這個類裡不包含其他的方法
* 3.更改測試執行器Suite.class
* 4.將要測試的類作為陣列傳入到Suite.SuiteClasses({})
*/
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

JUnit4引數化設定的介紹和使用:

如果測試程式碼大同小異,程式碼結構都是相同的,不同的只是測試的資料和預期值,那麼有沒有更好的辦法將相同的程式碼結構提取出來,提高程式碼的重用度呢?,那就要使用引數化測試了,以下是基本步驟:

1.要進行引數化測試,需要在類上面指定如下的執行器:@RunWith(Parameterized.class)
2.然後,在提供資料的方法上加上一個@Parameters註解,這個方法必須是靜態static的,並且返回一個集合Collection
3.在測試類的構造方法中為各個引數賦值,(構造方法是由JUnit呼叫的),最後編寫測試類,它會根據引數的組數來執行測試多次
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
@RunWith(Parameterized.class) //1.更改預設的測試執行器為RunWith(Parameterized.class)
public class ParameterTest{ //2.宣告變數存放預期值和測試資料:
int expected =0;
int input1 = 0;
int input2 = 0; //3.宣告一個返回值為Collection的公共靜態方法,並使用@Parameters進行修飾:
@Parameters
public static Collection<Object[]><object> data() {
return Arrays.asList(new Object[][]{
{3,1,2},
{4,2,2}
}) ;
} //4.為測試類宣告一個帶有引數的公共建構函式,並在其中為之宣告變數賦值:
public ParameterTest(int expected,int input1,int input2){
this.expected = expected;
this.input1 = input1;
this.input2 = input2;
} //5.執行測試方法,即可完成對多組資料的測試:
@Test
public void testAdd(){
assertEquals(expected, new Calculate().add(input1, input2));
}
}

一、環境搭建

對於習慣使用Eclipse開發平臺來說,Junit早已是非常通常的外掛,在Eclipse開發平臺中,可以非常方便地搭建Junit測試環境。

1、在Eclipse上建立工程,任何Java工程都行。

2、引入Junit的libraries庫,選用Junit4。如下圖所示:

3、新建一個Java類,用於演示Junit4類的自動生成,java程式碼如下:

  1. package com.hy;
  2. public class Demo {
  3. public void method1() {
  4. System.out.println("method1");
  5. }
  6. public void method2() {
  7. System.out.println("method2");
  8. }
  9. public void method3() {
  10. System.out.println("method3");
  11. }
  12. }

4、在該類上右鍵單擊新建,選JUnit Test Case,自動生成一個對應的測試類,如下圖所示:

4、這樣就能自動地生成對應的測試類了,測試類程式碼發下:

[java] view plaincopy

  1. package com.hy;
  2. import static org.junit.Assert.*;
  3. import org.junit.After;
  4. import org.junit.AfterClass;
  5. import org.junit.Before;
  6. import org.junit.BeforeClass;
  7. import org.junit.Test;
  8. public class DemoTest {
  9. @BeforeClass
  10. public static void setUpBeforeClass() throws Exception {
  11. }
  12. @AfterClass
  13. public static void tearDownAfterClass() throws Exception {
  14. }
  15. @Before
  16. public void setUp() throws Exception {
  17. }
  18. @After
  19. public void tearDown() throws Exception {
  20. }
  21. @Test
  22. public void testMethod1() {
  23. fail("Not yet implemented");
  24. }
  25. @Test
  26. public void testMethod2() {
  27. fail("Not yet implemented");
  28. }
  29. @Test
  30. public void testMethod3() {
  31. fail("Not yet implemented");
  32. }
  33. }

5、如此一來,測試類環境的搭建過程就完成了,最後要做的就是,根據實際的業務需求,對測試類中的測試方法編寫單元測試程式碼,直到執行調通。

二、基本規則

從上面的演示可知,測試類名一般都以Test結尾,測試方法名以test開頭。這個也是Junit的基本命名規則。

三、Junit註解

我們此次針對的是Junit4版本,註解也是在Junit4版本才有的,之前的版本並無註解功能。而註解開發基本上被認為是一種優秀的設計,所以我們寫單元測試用例時,儘可能地去了解並使用註解。

@Test:使用該註解的方法為測試方法,自動執行時能夠識別並被執行

包含兩個引數:expected=XXXException.class 期望出現的異常

timeout=xxx 設定程式執行的超時時間

@Ignore:被忽略的測試方法

@Before:在每個測試方法之前執行

@After: 在每個測試方法之後執行

@BeforeClass:在所有測試開始之前執行

@AfterClass:在所有測試開始之後執行

以上幾個就是Junit 4的關鍵註解,熟練使用這幾個註解,將來的測試用例編寫肯定能事半功倍。

注意:@Before與@BeforeClass的區別

@Before會加在每個方法前執行,即有幾個@Test就會執行幾遍。

@BeforeClass 只在所有測試之前執行,只會執行一次。並且@BeforeClass修飾的方法必須是公有的靜態方法(public static )。

@After和@AfterClass也類似

每個測試類中這四個註解不能重複使用,一個方法只能從這四個註解中挑選其中一個。

四、基本寫法

1、setUp(),tearDown(),setUpBeforeClass(),tearDownAfterClass()這四個方法其實就是對應的@Before、@BeforeClass、@After、@AfterClass這四個註解,在Junit4開始使用註解時,其實可以替代這四個方法的功能,只是這四個方法是歷史遺留方法,可以考慮使用,也可以直接使用註解替代。

2、Assert是單元測試用例的核心,建議使用靜態匯入。

3、待測試物件,一般建議設計成靜態的。

4、測試方法的要求:帶@Test註解,方法名隨意,返回值必須為void,不能帶有引數,可以宣告異常(可以參考演示程式碼)。

5、Fixture方法的作用

前面介紹的@Before、@BeforeClass、@After、@AfterClass註解修飾的方法,即為Fixture方法,它是在某些階段必然被呼叫的方法,如註解功能所示。

@Before、@After修飾方法的一個用處是對待測試物件的“復原”操作,如成員變量回歸,資料庫回滾等,目的是消除@Test方法之間的耦合。也可以用來列印日誌。

@BeforeClass修飾方法可以設計成用來載入一些耗時耗力的操作,如檔案流的讀取,資料庫連線等,然後在@AfterClass中釋放對應的資源即可。

6、限時測試

@Test(timeout=1000)超時時間單位為毫秒

用於測試是否有死迴圈工是實時性要求比較高的用例,這個非常方便而且非常有用。

7、測試異常

@Test(expected=XXXException.class) XXXException為宣告式異常

用來驗證宣告式異常,注意此測試的含義:出現了期望的異常,叫做正常,若沒出現異常,Junit會報錯,認為不正常。這段描述有些拗口,請各位多琢磨琢磨。

8、執行器Runner

類註解@RunWith,指定不同的類可以改變測試類的行為

9、引數化測試

主要是針對一些相同功能卻要進行多組引數測試的情況,開發步驟如下:

1)引數化測試的類和普通測試類不同,要用特殊的Runner,類註解需要改為@RunWith(Parameterized.class)

2)定義該測試類的成員變數,一個放測試引數,另一個放該引數產生的預期結果

3)定義測試資料集合方法 public static Collection data() {...},注意該方法要用@Parameters修飾(資料格式為二維陣列)

4)定義帶引數的建構函式,注意定義資料集合時,要和建構函式引數次序一致

其他的與普通測試類似

注意:若測試資料有兩條,則該類下的所有@Test的方法都會執行兩次,所以引數化測試的類不要和別的@Test放在一起。引數化測試方法一般建議單獨建立類。

演示程式碼如下:

[java] view plaincopy

  1. //指定@RunWith
  2. @RunWith(Parameterized.class)
  3. public class ParamTest {
  4. //定義成員變數,i為測試引數,j為測試結果
  5. private int i;
  6. private int j;
  7. //建構函式
  8. public ParamTest(int i, int j) {
  9. super();
  10. this.i = i;
  11. this.j = j;
  12. }
  13. //測試資料集合,注意使用的註解,資料結構及次序
  14. @Parameters
  15. public static Collection data() {
  16. return Arrays.asList(new Object[][]{{1,2},{3,4},{4,6}});
  17. }
  18. @Test
  19. public void testMethod1() {
  20. System.out.println(i);
  21. System.out.println(j);
  22. //簡單測試,只測試引數加1會不會等於預期結果
  23. Assert.assertEquals(i+1, j);
  24. }
  25. }

預期的執行結果是前兩組引數測試正確,最後一組測試錯誤,執行後的結果為:

執行結果與預期結果相符合,OK

10、打包測試

將測試類集中起來執行,提高測試效率,程式碼如下:

[java] view plaincopy

  1. @RunWith(Suite.class)
  2. @Suite.SuiteClasses({
  3. DemoTest.class
  4. })
  5. public class ModuleTest {
  6. public ModuleTest() {
  7. // TODO Auto-generated constructor stub
  8. }
  9. }

1)@Suite.SuiteClasses裡面的是需要打包測試的類

2)該類中可以為空,類名建議為模組名+Test結尾,如ModuleTest.java。