国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java單元測試JUnit框架原理與用法實例教程

java單元測試JUnit框架原理與用法實例教程

2021-02-02 11:30維C果糖 Java教程

這篇文章主要介紹了java單元測試JUnit框架原理與用法,結合實例形式較為詳細的分析了java單元測試JUnit框架的概念、原理、使用方法及相關注意事項,需要的朋友可以參考下

本文實例講述了java單元測試JUnit框架原理與用法。分享給大家供大家參考,具體如下:

1 簡介

JUnit是一個Java語言的單元測試框架,它由 Kent Beck 和 Erich Gamma 建立,逐漸成為 xUnit 家族中最為成功的一個。 JUnit有它自己的JUnit擴展生態圈,多數Java的開發環境都已經集成了JUnit作為單元測試的工具。在這里,一個單元可以是一個方法、類、包或者子系統。因此,單元測試是指對代碼中的最小可測試單元進行檢查和驗證,以便確保它們正常工作。例如,我們可以給予一定的輸入測試輸出是否是所希望得到的結果。在本篇博客中,作者將著重介紹 JUnit 4.X 版本的特性,這也是我們在日常開發中使用最多的版本。

2 特點

JUnit提供了注釋以及確定的測試方法;
JUnit提供了斷言用于測試預期的結果;
JUnit測試優雅簡潔不需要花費太多的時間;
JUnit測試讓大家可以更快地編寫代碼并且提高質量;
JUnit測試可以組織成測試套件包含測試案例,甚至其他測試套件;
Junit顯示測試進度,如果測試是沒有問題條形是綠色的,測試失敗則會變成紅色;
JUnit測試可以自動運行,檢查自己的結果,并提供即時反饋,沒有必要通過測試結果報告來手動梳理。

3 內容

3.1 注解

@Test :該注釋表示,用其附著的公共無效方法(即用public修飾的void類型的方法 )可以作為一個測試用例;
@Before :該注釋表示,用其附著的方法必須在類中的每個測試之前執行,以便執行測試某些必要的先決條件;
@BeforeClass :該注釋表示,用其附著的靜態方法必須執行一次并在類的所有測試之前,發生這種情況時一般是測試計算共享配置方法,如連接到數據庫;
@After :該注釋表示,用其附著的方法在執行每項測試后執行,如執行每一個測試后重置某些變量,刪除臨時變量等;
@AfterClass :該注釋表示,當需要執行所有的測試在JUnit測試用例類后執行,AfterClass注解可以使用以清理建立方法,如斷開數據庫連接,注意:附有此批注(類似于BeforeClass)的方法必須定義為靜態;
@Ignore :該注釋表示,當想暫時禁用特定的測試執行可以使用忽略注釋,每個被注解為@Ignore的方法將不被執行。

?
1
2
3
4
5
6
7
8
9
10
11
/**
* JUnit 注解示例
*/
@Test
public void testYeepay(){
  Syetem.out.println("用@Test標示測試方法!");
}
@AfterClass
public static void paylus(){
  Syetem.out.println("用@AfterClass標示的方法在測試用例類執行完之后!");
}

3.2 斷言

在這里,作者將介紹一些斷言方法,所有這些方法都來自 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

4 JUnit 3.X 和 JUnit 4.X 的區別

4.1 JUnit 3.X

(1)使用 JUnit 3.X 版本進行單元測試時,測試類必須要繼承于 TestCase 父類;
(2)測試方法需要遵循的原則:

① public的;
② void的;
③ 無方法參數;
④方法名稱必須以 test 開頭;

(3)不同的測試用例之間一定要保持完全的獨立性,不能有任何的關聯;
(4)要掌握好測試方法的順序,不能依賴于測試方法自己的執行順序。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 用 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());
  }
}

4.2 JUnit 4.X

(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 注解”了解更多的注解。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* 用 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) {
  }
}

4.3 特別提醒

通過以上兩個例子,我們已經可以大致知道 JUnit 3.X 和 JUnit 4.X 兩個版本的區別啦!首先,如果我們使用 JUnit 3.X,那么在我們寫的測試類的時候,一定要繼承 TestCase 類,但是如果我們使用 JUnit 4.X,則不需繼承 TestCase 類,直接使用注解就可以啦!在 JUnit 3.X 中,還強制要求測試方法的命名為“ testXxxx ”這種格式;在 JUnit 4.X 中,則不要求測試方法的命名格式,但作者還是建議測試方法統一命名為“ testXxxx ”這種格式,簡潔明了。

此外,在上面的兩個示例中,我們只給出了測試類,但是在這之前,還應該有一個被測試類,也就是我們真正要實現功能的類。現在,作者將給出上面示例中被測試的類,即 Operation 類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 定義了加減乘除的法則
*/
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;
  }
}

5 測試示例

5.1 示例一:簡單的 JUnit 3.X 測試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Collection;
/**
 * 1、創建一個測試類,繼承TestCase類
 */
public class SimpleTestDemo extends TestCase {
  public SimpleTestDemo(String name) {
    super(name);
  }
  /**
   * 2、寫一個測試方法,斷言期望的結果
   */
  public void testEmptyCollection(){
    Collection collection = new ArrayList();
    assertTrue(collection.isEmpty());
  }
  /**
   * 3、寫一個suite()方法,它會使用反射動態的創建一個包含所有的testXxxx方法的測試套件
   */
  public static Test suit(){
    return new TestSuite(SimpleTestDemo.class);
  }
  /**
   * 4、寫一個main()方法,以文本運行器的方式方便的運行測試
   */
  public static void main(String[] args) {
    junit.textui.TestRunner.run(suit());
  }
}

5.2 示例二:套件測試

首先,介紹一下套件測試,簡單來講,測試套件是指:一些測試不同類的用例,可以使用 @RunWith 和 @Suite 注解把所有的測試類套在一起,從而形成測試套件。如果有很多測試類,想讓它們都運行在同一時間,而不是單一地運行每個測試,套件測試是非常有用的。當一個類被注解為 @RunWith, JUnit 將調用其中的注解,以便運行測試類,而不使用內置的 JUnit 運行方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 待測試類
*/
import java.util.Arrays;
public class GotoWork {
  public String[] prepareSkills() {
    String[] skill = { "Java", "MySQL", "JSP" };
    System.out.println("My skills include : " + Arrays.toString(skill));
    return skill;
  }
  public String[] addSkills() {
    String[] skill = { "Java", "MySQL", "JSP", "JUnit" };
    System.out.println("Look, my skills include : " + Arrays.toString(skill));
    return skill;
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 測試類 1
*/
import org.junit.Test;
import static org.junit.Assert.*;
public class PrepareSkillsTest {
  GotoWork gotoWork = new GotoWork();
  String[] skill = { "Java", "MySQL", "JSP" };
  @Test
  public void testPrepareSkills() {
    System.out.println("Inside testPrepareSkills()");
    assertArrayEquals(skill, gotoWork.prepareSkills());
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 測試類 2
*/
import org.junit.Test;
import static org.junit.Assert.*;
public class AddSkillsTest {
  GotoWork gotoWork = new GotoWork();
  String[] skill = { "Java", "MySQL", "JSP", "JUnit" };
  @Test
  public void testAddSkills() {
    System.out.println("Inside testAddPencils()");
    assertArrayEquals(skill, gotoWork.addSkills());
  }
}
?
1
2
3
4
5
6
7
8
9
/**
* 套件測試
*/
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ PrepareSkillsTest.class, AddSkillsTest.class })
public class SuitTest {
}

使用 @Suite.SuiteClasses 注解,可以定義測試類,將被列入執行,并且執行的順序就是在 @Suite.SuiteClasses 注解中定義的順序。

5.3 示例三:參數化測試

首先介紹一下參數化測試,一個測試類可以被看作是一個參數化測試類,當其滿足下列所有要求:

① 該類被注解為 @RunWith(Parameterized.class);
② 該類有一個構造函數,存儲測試數據;
③ 該類有一個靜態方法生成并返回測試數據,并標注 @Parameters 注解;
④ 該類有一個測試方法,即用注解 @Test 標注的方法。

?
1
2
3
4
5
6
7
8
9
/**
* 待測試類
*/
public class Calculate {
  public int sum(int var1, int var2) {
    System.out.println("此方法的參數值分別為 : " + var1 + " + " + var2);
    return var1 + var2;
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 參數化測試類
*/
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class CalculateTest {
  private int expected;
  private int first;
  private int second;
  public CalculateTest(int expectedResult, int firstNumber, int secondNumber) {
    this.expected = expectedResult;
    this.first = firstNumber;
    this.second = secondNumber;
  }
  @Parameters
  public static Collection addedNumbers() {
    return Arrays.asList(new Integer[][] { { 3, 1, 2 }, { 5, 2, 3 }, { 7, 3, 4 }, { 9, 4, 5 }, });
  }
  @Test
  public void testSum() {
    Calculate add = new Calculate();
    System.out.println("Addition with parameters : " + first + " and " + second);
    assertEquals(expected, add.sum(first, second));
  }
}

觀察 CalculateTest 類,它滿足上述所有的要求,因此它就可以稱為一個參數化測試類。addedNumbers 方法使用注釋 @Parameters 返回數組的集合,每個數組包括每個測試執行輸入和輸出數字,每個數組中的元素數必須相同好與構造參數的個數相匹配。所以,在這種特定的情況下,每個數組包括三個元素,即表示要加入的兩個元素和一個結果元素。

6 個人建議

有些童鞋可能會有一些誤解,認為寫測試代碼沒有用,而且還會增大自己的壓力,浪費時間。但事實上,寫測試代碼與否,還是有很大區別的,如果是在小的項目中,或許這種區別還不太明顯,但如果在大型項目中,一旦出現錯誤或異常,用人力去排查的話,那將會浪費很多時間,而且還不一定排查的出來,但是如果用測試代碼的話,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. 使用文檔生成器做測試文檔。

事實上,在 Junit 中使用 try catch 來捕獲異常是沒有必要的,因為 Junit 會自動捕獲異常,那些沒有被捕獲的異常就會被當成錯誤處理啦!

希望本文所述對大家java程序設計有所幫助。

原文鏈接:http://blog.csdn.net/qq_35246620/article/details/54620207

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 黄色三级视频 | 色综合久 | 亚色在线| 成人aaa| 欧美精品一区二区三区蜜桃视频 | 伊大人久久香线焦宗合一75大 | 国产成人精品一区二区三区四区 | 在线免费观看h片 | 成人欧美一区二区 | 成人高清在线视频 | 成人欧美一区二区三区在线观看 | 丝袜美腿一区二区三区 | 欧美黑人一级爽快片淫片高清 | 吴梦梦到粉丝家实战华中在线观看 | 亚洲成人av一区二区 | 男女爱爱免费视频 | 日韩欧美视频在线 | 欧美精品1区| 黄色精品一区二区 | 涩涩视频在线看 | 欧美精品日韩 | 国产一级一级国产 | 杨门女将寡妇一级裸片看 | 四虎影院网 | 欧美视频免费在线 | 久久亚洲国产精品 | 免费av一区二区三区 | 欧美亚洲国产激情 | 久久精品综合 | 成人午夜在线视频 | 国产精品一二三 | 精品福利一区二区三区 | 亚洲精品一区二区三区在线 | 日本在线一区二区三区 | 精品2区 | 日韩免费高清视频 | 久久久精品视频国产 | 久久91久久久久麻豆精品 | 欧美日韩久久久久 | 久草在线视频网 | 亚洲久久久久 |