java語言

當前位置 /首頁/計算機/java語言/列表

編寫更好的Java單元測試的7個技巧

測試是開發的一個非常重要的方面,可以在很大程度上決定一個應用程式的命運。良好的測試可以在早期捕獲導致應用程式崩潰的問題,但較差的測試往往總是導致故障和停機。

編寫更好的Java單元測試的7個技巧

雖然有三種主要型別的軟體測試:單元測試,功能測試和整合測試,但是在這篇博文中,我們將討論開發人員級單元測試。在我深入講述具體細節之前,讓我們先來回顧一下這三種測試的詳細內容。

  軟體開發測試的型別:

單元測試用於測試各個程式碼元件,並確保程式碼按照預期的方式工作。單元測試由開發人員編寫和執行。大多數情況下,使用JUnit或TestNG之類的測試框架。測試用例通常是在方法級別寫入並通過自動化執行。

整合測試檢查系統是否作為一個整體而工作。整合測試也由開發人員完成,但不是測試單個元件,而是旨在跨元件測試。系統由許多單獨的元件組成,如程式碼,資料庫,Web伺服器等。整合測試能夠發現如元件佈線,網路訪問,資料庫問題等問題。

功能測試通過將給定輸入的結果與規範進行比較來檢查每個功能是否正確實現。通常,這不是在開發人員級別的。功能測試由單獨的測試團隊執行。測試用例基於規範編寫,並且實際結果與預期結果進行比較。有若干工具可用於自動化的功能測試,如Selenium和QTP。

如前所述,單元測試可幫助開發人員確定程式碼是否正常工作。在這篇博文中,我將提供在Java中單元測試的有用提示。

  1.使用框架來用於單元測試

Java提供了若干用於單元測試的框架。TestNG和JUnit是最流行的測試框架。JUnit和TestNG的一些重要功能:

易於設定和執行。

支援註釋

允許忽略或分組並一起執行某些測試。

支援引數化測試,即通過在執行時指定不同的值來執行單元測試。

通過與構建工具,如Ant,Maven和Gradle整合來支援自動化的測試執行。

EasyMock是一個模擬框架,是單元測試框架,如JUnit和TestNG的補充。EasyMock本身不是一個完整的框架。它只是添加了建立模擬物件以便於測試的能力。例如,我們想要測試的一個方法可以呼叫從資料庫獲取資料的DAO類。在這種情況下,EasyMock可用於建立返回硬編碼資料的MockDAO。這使我們能夠輕鬆地測試我們意向的方法,而不必擔心資料庫訪問。

  2.謹慎使用測試驅動開發!

測試驅動開發(TDD)是一個軟體開發過程,在這過程中,在開始任何編碼之前,我們基於需求來編寫測試。由於還沒有編碼,測試最初會失敗。然後寫入最小量的程式碼以通過測試。然後重構程式碼,直到被優化。

目標是編寫覆蓋所有需求的測試,而不是一開始就寫程式碼,卻可能甚至都不能滿足需求。TDD是偉大的,因為它導致簡單的模組化程式碼,且易於維護。總體開發速度加快,容易發現缺陷。此外,單元測試被建立作為TDD方法的副產品。

然而,TDD可能不適合所有的'情況。在設計複雜的專案中,專注於最簡單的設計以便於通過測試用例,而不提前思考可能會導致巨大的程式碼更改。此外,TDD方法難以用於與遺留系統,GUI應用程式或與資料庫一起工作的應用程式互動的系統。另外,測試需要隨著程式碼的改變而更新。

因此,在決定採用TDD方法之前,應考慮上述因素,並應根據專案的性質採取措施。

  3.測量程式碼覆蓋率

程式碼覆蓋率衡量(以百分比表示)了在執行單元測試時執行的程式碼量。通常,高覆蓋率的程式碼包含未檢測到的錯誤的機率要低,因為其更多的原始碼在測試過程中被執行。測量程式碼覆蓋率的一些最佳做法包括:

使用程式碼覆蓋工具,如Clover,Corbetura,JaCoCo或Sonar。使用工具可以提高測試質量,因為這些工具可以指出未經測試的程式碼區域,讓你能夠開發開發額外的測試來覆蓋這些領域。

每當寫入新功能時,立即寫新的測試覆蓋。

確保有測試用例覆蓋程式碼的所有分支,即if / else語句。

高程式碼覆蓋不能保證測試是完美的,所以要小心!

下面的concat方法接受布林值作為輸入,並且僅當布林值為true時附加傳遞兩個字串:

public String concat(boolean append, String a,String b) {

String result = null;

If (append) {

result = a + b;

}

return werCase();

以下是上述方法的測試用例:

@Test

public void testStringUtil() {

String result = at(true, "Hello ", "World");

tln("Result is "+result);

}

}

在這種情況下,執行測試的值為true。當測試執行時,它將通過。當代碼覆蓋率工具執行時,它將顯示100%的程式碼覆蓋率,因為concat方法中的所有程式碼都被執行。但是,如果測試執行的值為false,則將丟擲NullPointerException。所以100%的程式碼覆蓋率並不真正表明測試覆蓋了所有場景,也不能說明測試良好。

 4.儘可能將測試資料外部化

在JUnit4之前,測試用例要執行的資料必須硬編碼到測試用例中。這導致了限制,為了使用不同的資料執行測試,測試用例程式碼必須修改。但是,JUnit4以及TestNG支援外部化測試資料,以便可以針對不同的資料集執行測試用例,而無需更改原始碼。

下面的MathChecker類有方法可以檢查一個數字是否是奇數:

public class MathChecker {

public Boolean isOdd(int n) {

if (n%2 != 0) {

return true;

} else {

return false;

}

}

}

以下是MathChecker類的TestNG測試用例:

public class MathCheckerTest {

private MathChecker checker;

@BeforeMethod

public void beforeMethod() {

checker = new MathChecker();

}

@Test

@Parameters("num")

public void isOdd(int num) {

tln("Running test for "+num);

Boolean result = d(num);

rtEquals(result, new Boolean(true));

}

}

TestNG

以下是(用於TestNG的配置檔案),它具有要為其執行測試的資料: 

可以看出,在這種情況下,測試將執行兩次,值3和7各一次。除了通過XML配置檔案指定測試資料之外,還可以通過DataProvider註釋在類中提供測試資料。

JUnit

與TestNG類似,測試資料也可以外部化用於JUnit。以下是與上述相同MathChecker類的JUnit測試用例:

TAG標籤:編寫 JAVA 單元測試 #