偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

編寫(xiě)更好的Java單元測(cè)試的七個(gè)技巧

開(kāi)發(fā) 后端
測(cè)試是開(kāi)發(fā)的一個(gè)非常重要的方面,可以在很大程度上決定一個(gè)應(yīng)用程序的命運(yùn)。良好的測(cè)試可以在早期捕獲導(dǎo)致應(yīng)用程序崩潰的問(wèn)題,但較差的測(cè)試往往總是導(dǎo)致故障和停機(jī)。

測(cè)試是開(kāi)發(fā)的一個(gè)非常重要的方面,可以在很大程度上決定一個(gè)應(yīng)用程序的命運(yùn)。良好的測(cè)試可以在早期捕獲導(dǎo)致應(yīng)用程序崩潰的問(wèn)題,但較差的測(cè)試往往總是導(dǎo)致故障和停機(jī)。

雖然有三種主要類(lèi)型的軟件測(cè)試:?jiǎn)卧獪y(cè)試,功能測(cè)試和集成測(cè)試,但是在這篇博文中,我們將討論開(kāi)發(fā)人員級(jí)單元測(cè)試。在我深入講述具體細(xì)節(jié)之前,讓我們先來(lái)回顧一下這三種測(cè)試的詳細(xì)內(nèi)容。

[[178747]]

軟件開(kāi)發(fā)測(cè)試的類(lèi)型

單元測(cè)試用于測(cè)試各個(gè)代碼組件,并確保代碼按照預(yù)期的方式工作。單元測(cè)試由開(kāi)發(fā)人員編寫(xiě)和執(zhí)行。大多數(shù)情況下,使用JUnit或TestNG之類(lèi)的測(cè)試框架。測(cè)試用例通常是在方法級(jí)別寫(xiě)入并通過(guò)自動(dòng)化執(zhí)行。

集成測(cè)試檢查系統(tǒng)是否作為一個(gè)整體而工作。集成測(cè)試也由開(kāi)發(fā)人員完成,但不是測(cè)試單個(gè)組件,而是旨在跨組件測(cè)試。系統(tǒng)由許多單獨(dú)的組件組成,如代碼,數(shù)據(jù)庫(kù),Web服務(wù)器等。集成測(cè)試能夠發(fā)現(xiàn)如組件布線(xiàn),網(wǎng)絡(luò)訪(fǎng)問(wèn),數(shù)據(jù)庫(kù)問(wèn)題等問(wèn)題。

功能測(cè)試通過(guò)將給定輸入的結(jié)果與規(guī)范進(jìn)行比較來(lái)檢查每個(gè)功能是否正確實(shí)現(xiàn)。通常,這不是在開(kāi)發(fā)人員級(jí)別的。功能測(cè)試由單獨(dú)的測(cè)試團(tuán)隊(duì)執(zhí)行。測(cè)試用例基于規(guī)范編寫(xiě),并且實(shí)際結(jié)果與預(yù)期結(jié)果進(jìn)行比較。有若干工具可用于自動(dòng)化的功能測(cè)試,如Selenium和QTP。

如前所述,單元測(cè)試可幫助開(kāi)發(fā)人員確定代碼是否正常工作。在這篇博文中,我將提供在Java中單元測(cè)試的有用提示。

1.使用框架來(lái)用于單元測(cè)試

Java提供了若干用于單元測(cè)試的框架。TestNG和JUnit是***的測(cè)試框架。JUnit和TestNG的一些重要功能:

  • 易于設(shè)置和運(yùn)行。

  • 支持注釋。

  • 允許忽略或分組并一起執(zhí)行某些測(cè)試。

  • 支持參數(shù)化測(cè)試,即通過(guò)在運(yùn)行時(shí)指定不同的值來(lái)運(yùn)行單元測(cè)試。

  • 通過(guò)與構(gòu)建工具,如Ant,Maven和Gradle集成來(lái)支持自動(dòng)化的測(cè)試執(zhí)行。

EasyMock是一個(gè)模擬框架,是單元測(cè)試框架,如JUnit和TestNG的補(bǔ)充。EasyMock本身不是一個(gè)完整的框架。它只是添加了創(chuàng)建模擬對(duì)象以便于測(cè)試的能力。例如,我們想要測(cè)試的一個(gè)方法可以調(diào)用從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)的DAO類(lèi)。在這種情況下,EasyMock可用于創(chuàng)建返回硬編碼數(shù)據(jù)的MockDAO。這使我們能夠輕松地測(cè)試我們意向的方法,而不必?fù)?dān)心數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)。

2.謹(jǐn)慎使用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)!

測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)是一個(gè)軟件開(kāi)發(fā)過(guò)程,在這過(guò)程中,在開(kāi)始任何編碼之前,我們基于需求來(lái)編寫(xiě)測(cè)試。由于還沒(méi)有編碼,測(cè)試最初會(huì)失敗。然后寫(xiě)入最小量的代碼以通過(guò)測(cè)試。然后重構(gòu)代碼,直到被優(yōu)化。

目標(biāo)是編寫(xiě)覆蓋所有需求的測(cè)試,而不是一開(kāi)始就寫(xiě)代碼,卻可能甚至都不能滿(mǎn)足需求。TDD是偉大的,因?yàn)樗鼘?dǎo)致簡(jiǎn)單的模塊化代碼,且易于維護(hù)。總體開(kāi)發(fā)速度加快,容易發(fā)現(xiàn)缺陷。此外,單元測(cè)試被創(chuàng)建作為T(mén)DD方法的副產(chǎn)品。

然而,TDD可能不適合所有的情況。在設(shè)計(jì)復(fù)雜的項(xiàng)目中,專(zhuān)注于最簡(jiǎn)單的設(shè)計(jì)以便于通過(guò)測(cè)試用例,而不提前思考可能會(huì)導(dǎo)致巨大的代碼更改。此外,TDD方法難以用于與遺留系統(tǒng),GUI應(yīng)用程序或與數(shù)據(jù)庫(kù)一起工作的應(yīng)用程序交互的系統(tǒng)。另外,測(cè)試需要隨著代碼的改變而更新。

因此,在決定采用TDD方法之前,應(yīng)考慮上述因素,并應(yīng)根據(jù)項(xiàng)目的性質(zhì)采取措施。

3.測(cè)量代碼覆蓋率

代碼覆蓋率衡量(以百分比表示)了在運(yùn)行單元測(cè)試時(shí)執(zhí)行的代碼量。通常,高覆蓋率的代碼包含未檢測(cè)到的錯(cuò)誤的幾率要低,因?yàn)槠涓嗟脑创a在測(cè)試過(guò)程中被執(zhí)行。測(cè)量代碼覆蓋率的一些***做法包括:

  • 使用代碼覆蓋工具,如Clover,Corbetura,JaCoCo或Sonar。使用工具可以提高測(cè)試質(zhì)量,因?yàn)檫@些工具可以指出未經(jīng)測(cè)試的代碼區(qū)域,讓你能夠開(kāi)發(fā)開(kāi)發(fā)額外的測(cè)試來(lái)覆蓋這些領(lǐng)域。

  • 每當(dāng)寫(xiě)入新功能時(shí),立即寫(xiě)新的測(cè)試覆蓋。

  • 確保有測(cè)試用例覆蓋代碼的所有分支,即if / else語(yǔ)句。

高代碼覆蓋不能保證測(cè)試是***的,所以要小心!

下面的concat方法接受布爾值作為輸入,并且僅當(dāng)布爾值為true時(shí)附加傳遞兩個(gè)字符串:

  1. public String concat(boolean append, String a,String b) { 
  2.         String result = null
  3.         If (append) { 
  4.             result = a + b; 
  5.                             } 
  6.         return result.toLowerCase(); 

以下是上述方法的測(cè)試用例:

  1. @Test 
  2. public void testStringUtil() { 
  3.      String result = stringUtil.concat(true"Hello ""World"); System.out.println("Result is "+result); 

在這種情況下,執(zhí)行測(cè)試的值為true。當(dāng)測(cè)試執(zhí)行時(shí),它將通過(guò)。當(dāng)代碼覆蓋率工具運(yùn)行時(shí),它將顯示100%的代碼覆蓋率,因?yàn)?code>concat方法中的所有代碼都被執(zhí)行。但是,如果測(cè)試執(zhí)行的值為false,則將拋出NullPointerException。所以100%的代碼覆蓋率并不真正表明測(cè)試覆蓋了所有場(chǎng)景,也不能說(shuō)明測(cè)試良好。

4.盡可能將測(cè)試數(shù)據(jù)外部化

在JUnit4之前,測(cè)試用例要運(yùn)行的數(shù)據(jù)必須硬編碼到測(cè)試用例中。這導(dǎo)致了限制,為了使用不同的數(shù)據(jù)運(yùn)行測(cè)試,測(cè)試用例代碼必須修改。但是,JUnit4以及TestNG支持外部化測(cè)試數(shù)據(jù),以便可以針對(duì)不同的數(shù)據(jù)集運(yùn)行測(cè)試用例,而無(wú)需更改源代碼。

下面的MathChecker類(lèi)有方法可以檢查一個(gè)數(shù)字是否是奇數(shù):

  1. public class MathChecker { 
  2.         public Boolean isOdd(int n) { 
  3.             if (n%2 != 0) { 
  4.                 return true
  5.             } else { 
  6.                 return false
  7.             } 
  8.         } 
  9.     } 

以下是MathChecker類(lèi)的TestNG測(cè)試用例:

  1. public class MathCheckerTest { 
  2.         private MathChecker checker; 
  3.         @BeforeMethod 
  4.         public void beforeMethod() { 
  5.           checker = new MathChecker(); 
  6.         } 
  7.         @Test 
  8.         @Parameters("num"public void isOdd(int num) { System.out.println("Running test for "+num); Boolean result = checker.isOdd(num); Assert.assertEquals(result, new Boolean(true)); 
  9.         } 
  10.     } 

TestNG

以下是testng.xml(用于TestNG的配置文件),它具有要為其執(zhí)行測(cè)試的數(shù)據(jù):

 

  1. <xml version="1.0" encoding="UTF-8"?> 
  2. <suite name="ParameterExampleSuite" parallel="false"
  3. <test name="MathCheckerTest"
  4. <classes> 
  5.   <parameter name="num" value="3"></parameter> 
  6.   <class name="com.stormpath.demo.MathCheckerTest"/> 
  7. </classes> 
  8.  </test> 
  9.  <test name="MathCheckerTest1"
  10. <classes> 
  11.   <parameter name="num" value="7"></parameter> 
  12.   <class name="com.stormpath.demo.MathCheckerTest"/> 
  13. </classes> 
  14.  </test> 
  15. </suite> 

可以看出,在這種情況下,測(cè)試將執(zhí)行兩次,值3和7各一次。除了通過(guò)XML配置文件指定測(cè)試數(shù)據(jù)之外,還可以通過(guò)DataProvider注釋在類(lèi)中提供測(cè)試數(shù)據(jù)。

JUnit

與TestNG類(lèi)似,測(cè)試數(shù)據(jù)也可以外部化用于JUnit。以下是與上述相同MathChecker類(lèi)的JUnit測(cè)試用例:

 

  1. @RunWith(Parameterized.class
  2. public class MathCheckerTest { 
  3.  private int inputNumber; 
  4.  private Boolean expected; 
  5.  private MathChecker mathChecker; 
  6.  @Before 
  7.  public void setup(){ 
  8.      mathChecker = new MathChecker(); 
  9.  } 
  10.     // Inject via constructor 
  11.     public MathCheckerTest(int inputNumber, Boolean expected) { 
  12.         this.inputNumber = inputNumber; 
  13.         this.expected = expected; 
  14.     } 
  15.     @Parameterized.Parameters 
  16.     public static Collection<Object[]> getTestData() { 
  17.         return Arrays.asList(new Object[][]{ 
  18.                 {1true}, 
  19.                 {2false}, 
  20.                 {3true}, 
  21.                 {4false}, 
  22.                 {5true
  23.         }); 
  24.     } 
  25.     @Test 
  26.     public void testisOdd() { 
  27.         System.out.println("Running test for:"+inputNumber); 
  28.         assertEquals(mathChecker.isOdd(inputNumber), expected); 
  29.     } 

可以看出,要對(duì)其執(zhí)行測(cè)試的測(cè)試數(shù)據(jù)由getTestData()方法指定。此方法可以輕松地修改為從外部文件讀取數(shù)據(jù),而不是硬編碼數(shù)據(jù)。

5.使用斷言而不是Print語(yǔ)句

許多新手開(kāi)發(fā)人員習(xí)慣于在每行代碼之后編寫(xiě)System.out.println語(yǔ)句來(lái)驗(yàn)證代碼是否正確執(zhí)行。這種做法常常擴(kuò)展到單元測(cè)試,從而導(dǎo)致測(cè)試代碼變得雜亂。除了混亂,這需要開(kāi)發(fā)人員手動(dòng)干預(yù)去驗(yàn)證控制臺(tái)上打印的輸出,以檢查測(cè)試是否成功運(yùn)行。更好的方法是使用自動(dòng)指示測(cè)試結(jié)果的斷言。

下面的StringUti類(lèi)是一個(gè)簡(jiǎn)單類(lèi),有一個(gè)連接兩個(gè)輸入字符串并返回結(jié)果的方法:

 

  1. public class StringUtil { 
  2.         public String concat(String a,String b) { 
  3.             return a + b; 
  4.         } 
  5.     } 

以下是上述方法的兩個(gè)單元測(cè)試:

 

  1. @Test 
  2.     public void testStringUtil_Bad() { 
  3.          String result = stringUtil.concat("Hello ""World"); 
  4.          System.out.println("Result is "+result); 
  5.     } 
  6.     @Test 
  7.     public void testStringUtil_Good() { 
  8.          String result = stringUtil.concat("Hello ""World"); 
  9.          assertEquals("Hello World", result); 
  10.     } 

testStringUtil\_Bad將始終傳遞,因?yàn)樗鼪](méi)有斷言。開(kāi)發(fā)人員需要手動(dòng)地在控制臺(tái)驗(yàn)證測(cè)試的輸出。如果方法返回錯(cuò)誤的結(jié)果并且不需要開(kāi)發(fā)人員干預(yù),則testStringUtil\_Good將失敗。

6.構(gòu)建具有確定性結(jié)果的測(cè)試

一些方法不具有確定性結(jié)果,即該方法的輸出不是預(yù)先知道的,并且每一次都可以改變。例如,考慮以下代碼,它有一個(gè)復(fù)雜的函數(shù)和一個(gè)計(jì)算執(zhí)行復(fù)雜函數(shù)所需時(shí)間(以毫秒為單位)的方法:

 

  1. public class DemoLogic { 
  2.  private void veryComplexFunction(){ 
  3.      //This is a complex function that has a lot of database access and is time consuming 
  4.      //To demo this method, I am going to add a Thread.sleep for a random number of milliseconds 
  5.      try { 
  6.          int time = (int) (Math.random()*100); 
  7.          Thread.sleep(time); 
  8.      } catch (InterruptedException e) { 
  9.          // TODO Auto-generated catch block 
  10.          e.printStackTrace(); 
  11.      } 
  12.  } 
  13.  public long calculateTime(){ 
  14.      long time = 0
  15.      long before = System.currentTimeMillis(); 
  16.      veryComplexFunction(); 
  17.      long after = System.currentTimeMillis(); 
  18.      time = after - before; 
  19.      return time; 
  20.  } 
  21.  } 

在這種情況下,每次執(zhí)行calculateTime方法時(shí),它將返回一個(gè)不同的值。為該方法編寫(xiě)測(cè)試用例不會(huì)有任何用處,因?yàn)樵摲椒ǖ妮敵鍪强勺兊摹R虼?,測(cè)試方法將不能驗(yàn)證任何特定執(zhí)行的輸出。

7.除了正面情景外,還要測(cè)試負(fù)面情景和邊緣情況

通常,開(kāi)發(fā)人員會(huì)花費(fèi)大量的時(shí)間和精力編寫(xiě)測(cè)試用例,以確保應(yīng)用程序按預(yù)期工作。然而,測(cè)試負(fù)面測(cè)試用例也很重要。負(fù)面測(cè)試用例指的是測(cè)試系統(tǒng)是否可以處理無(wú)效數(shù)據(jù)的測(cè)試用例。例如,考慮一個(gè)簡(jiǎn)單的函數(shù),它能讀取長(zhǎng)度為8的字母數(shù)字值,由用戶(hù)鍵入。除了字母數(shù)字值,應(yīng)測(cè)試以下負(fù)面測(cè)試用例:

  • 用戶(hù)指定非字母數(shù)字值,如特殊字符。

  • 用戶(hù)指定空值。

  • 用戶(hù)指定大于或小于8個(gè)字符的值。

類(lèi)似地,邊界測(cè)試用例測(cè)試系統(tǒng)是否適用于極端值。例如,如果用戶(hù)希望輸入從1到100的數(shù)字值,則1和100是邊界值,對(duì)這些值進(jìn)行測(cè)試系統(tǒng)是非常重要的。

譯文鏈接:http://www.codeceo.com/article/7-trends-java-unit-test.html
英文原文:7 Tips for Writing Better Unit Tests in Java

責(zé)任編輯:張燕妮 來(lái)源: 碼農(nóng)網(wǎng)
相關(guān)推薦

2021-09-27 13:02:05

Python技巧測(cè)試

2021-12-08 10:31:46

ITIT領(lǐng)導(dǎo)IT管理

2022-06-23 09:22:57

Vue技巧前端

2021-03-11 12:33:50

JavaPowerMock技巧

2024-06-25 15:41:41

2023-09-07 16:28:46

JavaScrip

2021-11-22 12:13:54

Linuxwget 命令

2021-08-17 10:08:44

HTML網(wǎng)站網(wǎng)絡(luò)

2022-04-14 10:40:11

領(lǐng)導(dǎo)者IT團(tuán)隊(duì)遠(yuǎn)程團(tuán)隊(duì)

2019-09-09 10:32:51

基于意圖的網(wǎng)絡(luò)IBN網(wǎng)絡(luò)

2024-10-16 16:09:32

2017-01-14 23:42:49

單元測(cè)試框架軟件測(cè)試

2014-02-25 10:25:52

單元測(cè)試測(cè)試

2022-07-14 10:34:13

IT領(lǐng)導(dǎo)者CIO首席信息官

2021-06-28 11:46:31

GitLinux

2018-04-27 09:22:21

數(shù)據(jù)存儲(chǔ)技巧

2025-03-21 08:20:00

數(shù)據(jù)清洗Python編程

2020-05-08 19:52:31

Reactreact.js前端

2011-05-16 16:52:09

單元測(cè)試徹底測(cè)試

2023-05-30 09:59:38

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)