Java單體應用 - 常用框架 - 03.JUnit

原文地址:http://www.work100.net/training/monolithic-frameworks-junit.html
更多教程:光束雲 - 免費課程

JUnit

序號 文內章節 視頻
1 TDD -
2 JUnit簡介 -
3 JUnit特點 -
4 實例 -
5 註解 -
6 斷言 -
7 實例源碼 -

請參照如上章節導航進行閱讀

1.TDD

TDD 是測試驅動開發(Test-Driven Development)的英文簡稱,是敏捷開發中的一項核心實踐和技術,也是一種設計方法論。

TDD 的原理是在開發功能代碼之前,先編寫單元測試用例代碼,測試代碼確定需要編寫什麼產品代碼。TDD雖是敏捷方法的核心實踐,但不只適用於XP(Extreme Programming),同樣可以適用於其他開發方法和過程。

TDD 的基本思路就是通過測試來推動整個開發的進行,但測試驅動開發並不只是單純的測試工作,而是把需求分析,設計,質量控制量化的過程。

TDD的重要目的不僅僅是測試軟件,測試工作保證代碼質量僅僅是其中一部分,而且是在開發過程中幫助客戶和程序員去除模棱兩可的需求。
TDD首先考慮使用需求(對象、功能、過程、接口等),主要是編寫測試用例框架對功能的過程和接口進行設計,而測試框架可以持續進行驗證。

2.JUnit簡介

JUnit 是用於編寫和運行可重複的自動化測試的開源測試框架,這樣可以保證我們的代碼按預期工作。JUnit 可廣泛用於工業和作爲支架(從命令行)或IDE(如 IDEA)內單獨的 Java 程序。

JUnit 提供:

  • 斷言測試預期結果。
  • 測試功能共享通用的測試數據。
  • 測試套件輕鬆地組織和運行測試。
  • 圖形和文本測試運行。

JUnit 用於測試:

  • 整個對象
  • 對象的一部分 - 交互的方法或一些方法
  • 幾個對象之間的互動(交互)

3.JUnit特點

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

4.實例

我們仍然以 hello-spring 項目進行代碼演示。

4.1.更新POM

修改 pom.xml 文件,增加 junit:junit 依賴:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.work100.training.stage2</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

4.2.創建測試類

在測試包下 src/test/java 創建一個名爲 MyTest 的測試類,代碼如下:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * <p>Title: MyTest</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-12 15:09
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-12   liuxiaojun     初始創建
 * -----------------------------------------------
 */
public class MyTest {
    /**
     * 執行測試方法前執行
     */
    @Before
    public void before() {
        System.out.println("執行 before() 方法");
    }

    /**
     * 執行測試方法後執行
     */
    @After
    public void after() {
        System.out.println("執行 after() 方法");
        System.out.println("-------------------------");
    }

    @Test
    public void testSayHi() {
        System.out.println("Hi Log4j");
    }

    @Test
    public void testSayHello() {
        System.out.println("Hello Log4j");
    }
}

5.註解

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

6.斷言

6.1.什麼是斷言

斷言是編程術語,表示爲一些布爾表達式,程序員相信在程序中的某個特定點該表達式值爲真,可以在任何時候啓用和禁用斷言驗證,因此可以在測試時啓用斷言而在部署時禁用斷言。同樣,程序投入運行後,最終用戶在遇到問題時可以重新啓用斷言。

使用斷言可以創建更穩定、品質更好且 不易於出錯的代碼。當需要在一個值爲 false 時中斷當前操作的話,可以使用斷言。單元測試必須使用斷言(Junit/JunitX)。

6.2.常用斷言方法

斷言 描述
void assertEquals([String message], expected value, actual value) 斷言兩個值相等。<br>值可能是類型有:int, short, long, byte, char or java.lang.Object。<br>第一個參數是一個可選的字符串消息
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) 斷言預期數組和結果數組相等。<br>數組的類型可能是:int, long, short, char, byte or java.lang.Object。

6.3.測試斷言效果

在之前的單元測試類中創建一個名爲 testAssert 方法,代碼如下:

/**
 * 測試斷言
 */
@Test
public void testAssert() {
    String obj1 = "junit";
    String obj2 = "junit";
    String obj3 = "test";
    String obj4 = "test";
    String obj5 = null;
    int var1 = 1;
    int var2 = 2;
    int[] arithmetic1 = {1, 2, 3};
    int[] arithmetic2 = {1, 2, 3};

    assertEquals(obj1, obj2);

    assertSame(obj3, obj4);

    assertNotSame(obj2, obj4);

    assertNotNull(obj1);

    assertNull(obj5);

    assertTrue("爲真", var1 == var2);

    assertArrayEquals(arithmetic1, arithmetic2);
}

運行,查看斷言效果:

執行 before() 方法
Hello Log4j
執行 after() 方法
-------------------------
執行 before() 方法
Hi Log4j
執行 after() 方法
-------------------------
執行 before() 方法
執行 after() 方法
-------------------------

java.lang.AssertionError: 爲真

    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.assertTrue(Assert.java:41)
    at MyTest.testAssert(MyTest.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:78)
    at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

7.實例源碼

實例源碼已經託管到如下地址:


上一篇:Spring

下一篇:Log4j


如果對課程內容感興趣,可以掃碼關注我們的 公衆號QQ羣,及時關注我們的課程更新

公衆號
QQ交流羣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章