日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

編寫更好的 Java 單元測試的 7 個(gè)技巧

瀏覽:297日期:2022-09-05 15:05:26

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

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

編寫更好的 Java 單元測試的 7 個(gè)技巧

軟件開發(fā)測試的類型

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

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

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

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

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

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

易于設(shè)置和運(yùn)行。 支持注釋。 允許忽略或分組并一起執(zhí)行某些測試。 支持參數(shù)化測試,即通過在運(yùn)行時(shí)指定不同的值來運(yùn)行單元測試。 通過與構(gòu)建工具,如Ant,Maven和Gradle集成來支持自動(dòng)化的測試執(zhí)行。

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

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

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

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

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

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

3.測量代碼覆蓋率

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

使用代碼覆蓋工具,如Clover,Corbetura,JaCoCo或Sonar。使用工具可以提高測試質(zhì)量,因?yàn)檫@些工具可以指出未經(jīng)測試的代碼區(qū)域,讓你能夠開發(fā)開發(fā)額外的測試來覆蓋這些領(lǐng)域。 每當(dāng)寫入新功能時(shí),立即寫新的測試覆蓋。 確保有測試用例覆蓋代碼的所有分支,即if / else語句。

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

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

public String concat(boolean append, String a,String b) {String result = null;If (append) { result = a + b; }return result.toLowerCase();}

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

@Testpublic void testStringUtil() { String result = stringUtil.concat(true, 'Hello ', 'World'); System.out.println('Result is '+result);}

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

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

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

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

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;@BeforeMethodpublic void beforeMethod() { checker = new MathChecker();}@Test@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));} } TestNG

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

<?xml version='1.0' encoding='UTF-8'?> <suite name='ParameterExampleSuite' parallel='false'> <test name='MathCheckerTest'> <classes> <parameter name='num' value='3'></parameter> <class name='com.stormpath.demo.MathCheckerTest'/> </classes> </test> <test name='MathCheckerTest1'> <classes> <parameter name='num' value='7'></parameter> <class name='com.stormpath.demo.MathCheckerTest'/> </classes> </test> </suite>

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

JUnit

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

@RunWith(Parameterized.class) public class MathCheckerTest { private int inputNumber; private Boolean expected; private MathChecker mathChecker; @Before public void setup(){ mathChecker = new MathChecker(); }// Inject via constructorpublic MathCheckerTest(int inputNumber, Boolean expected) { this.inputNumber = inputNumber; this.expected = expected;}@Parameterized.Parameterspublic static Collection<Object[]> getTestData() { return Arrays.asList(new Object[][]{ {1, true}, {2, false}, {3, true}, {4, false}, {5, true} });}@Testpublic void testisOdd() { System.out.println('Running test for:'+inputNumber); assertEquals(mathChecker.isOdd(inputNumber), expected);} }

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

5.使用斷言而不是Print語句

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

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

public class StringUtil {public String concat(String a,String b) { return a + b;} }

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

@Test public void testStringUtil_Bad() { String result = stringUtil.concat('Hello ', 'World'); System.out.println('Result is '+result); } @Test public void testStringUtil_Good() { String result = stringUtil.concat('Hello ', 'World'); assertEquals('Hello World', result); }

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

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

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

public class DemoLogic { private void veryComplexFunction(){//This is a complex function that has a lot of database access and is time consuming//To demo this method, I am going to add a Thread.sleep for a random number of millisecondstry { int time = (int) (Math.random()*100); Thread.sleep(time);} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace();} } public long calculateTime(){long time = 0;long before = System.currentTimeMillis();veryComplexFunction();long after = System.currentTimeMillis();time = after - before;return time; } }

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

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

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

用戶指定非字母數(shù)字值,如特殊字符。 用戶指定空值。 用戶指定大于或小于8個(gè)字符的值。

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

來自:http://blog.csdn.net/qq_35101189/article/details/53925268

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品日韩毛片| 亚洲精品一区二区妖精| 蜜臀av性久久久久蜜臀aⅴ流畅| 99久久婷婷这里只有精品| 日韩88av| 肉色欧美久久久久久久免费看| 国产一区二区三区不卡视频网站 | 欧洲在线一区| 久久青草久久| 91精品国产自产在线观看永久∴| 少妇精品导航| 91久久国产| 老司机久久99久久精品播放免费| 日韩中文欧美在线| 日韩欧美久久| 国产高清亚洲| 亚洲天堂免费电影| 激情五月色综合国产精品| 美女网站一区| 亚洲精品综合| 久久爱www成人| 美女一区网站| 欧美 日韩 国产一区二区在线视频 | 国产精品一页| 精品国产午夜| 亚洲高清成人| 丝袜美腿一区二区三区| 日韩精品一页| 精品日韩一区| 婷婷综合亚洲| 日韩影院免费视频| 国产日韩一区二区三免费高清| 久久69成人| 激情丁香综合| 日韩欧美中文字幕在线视频| 久久久久伊人| 国内精品福利| 日韩国产在线观看| 岛国av在线播放| 亚洲欧美日韩国产| 国产精品调教视频| 久久亚洲在线| 97成人超碰| 香蕉视频亚洲一级| 视频一区二区不卡| 国产精品夜夜夜| 久久久久免费av| 日日摸夜夜添夜夜添国产精品| 精品亚洲二区| 欧美一级鲁丝片| 91成人在线网站| 欧美国产极品| 亚洲免费黄色| 欧美日韩国产一区二区三区不卡| 日韩中文字幕无砖| 岛国av免费在线观看| 免费看日韩精品| 九九九精品视频| 亚洲神马久久| 丁香婷婷久久| 亚洲精品电影| 麻豆国产欧美日韩综合精品二区| 精品中文字幕一区二区三区av| 欧美天堂在线| 激情综合自拍| 激情欧美国产欧美| 久久精品99久久久| 五月天激情综合网| 麻豆精品在线| 亚洲一区二区av| 日韩国产一区二区| 国产情侣一区在线| 亚洲在线网站| 日韩不卡视频在线观看| 欧美亚洲tv| 欧美.日韩.国产.一区.二区| 国产精品99久久久久久董美香| 一本色道久久精品| 日本激情一区| 欧美日韩一区二区国产| 狠狠爱成人网| 不卡福利视频| 麻豆精品久久| 欧美在线不卡| 日韩专区欧美专区| 亚洲一级高清| 日本免费一区二区三区四区| 国产欧美日韩免费观看| 9色国产精品| 欧美日韩视频免费观看| 欧美视频二区| 亚洲人妖在线| 国产亚洲午夜| 蜜桃av.网站在线观看| 国产精品久久久免费| 亚洲一级大片| 亚洲欧美日韩国产| 91九色精品| 久久精品国产www456c0m| 久久久久久久欧美精品| 国产精品精品| 久久精品人人| 国产日韩欧美在线播放不卡| 91超碰国产精品| 久久久亚洲一区| 超碰成人av| 91亚洲成人| 国产一区二区三区不卡视频网站 | 久久亚洲成人| 日韩国产激情| 国产精品久久久久久久久久10秀| 国产日韩一区| 国产福利一区二区精品秒拍| 69堂精品视频在线播放| 日韩欧美中文字幕电影| 亚洲欧洲日韩精品在线| 麻豆久久精品| 国产视频一区欧美| av成人国产| 国产精品试看| 视频一区二区国产| 国产精品日韩欧美一区| 红桃视频欧美| 亚洲一区二区三区免费在线观看| 女主播福利一区| 欧美女激情福利| 国产在线不卡| 欧美女激情福利| 久久亚洲视频| 亚洲精品美女91| 欧美在线不卡| 麻豆一区二区三区| 国产在线观看91一区二区三区| 精品久久久亚洲| 日韩成人免费| 久久激情网站| 巨乳诱惑日韩免费av| 亚洲毛片网站| 国产日韩亚洲欧美精品| 久久成人福利| 国产精品高颜值在线观看| 麻豆理论在线观看| 精品中文一区| 综合在线一区| 国产精品亚洲欧美| 国产91在线精品| 久久久777| 午夜亚洲福利在线老司机| 亚洲综合福利| 国产精品v一区二区三区| 精品精品国产三级a∨在线| 韩国精品主播一区二区在线观看 | 久久精品欧美一区| 欧美精品一二| 日本国产欧美| 国产一区二区三区探花| 久久美女精品| 日本综合视频| 国产在线观看91一区二区三区| 亚洲精品一级二级| 欧美在线综合| 欧美国产免费| 成人一二三区| 亚洲免费网址| 国产精品欧美大片| 欧美成人基地| 亚洲日产国产精品| 国产精品**亚洲精品| 婷婷成人在线| 日韩av不卡在线观看| 国产精品黑丝在线播放| 羞羞答答国产精品www一本 | 久久亚洲黄色| 婷婷丁香综合| 国产精品天天看天天狠| 亚洲成人va| 日韩高清在线不卡| 麻豆成全视频免费观看在线看| 99视频精品| 国产激情久久| 好看的亚洲午夜视频在线| 国产精品一区二区精品| 久久亚洲国产| 国产精品久久久久久av公交车 | 樱桃视频成人在线观看| 亚洲资源av| 97精品一区| 亚洲制服欧美另类| 国产成人精品亚洲日本在线观看| 男女性色大片免费观看一区二区| 卡一精品卡二卡三网站乱码| 亚洲国产一区二区三区在线播放| 国产探花一区| 欧美不卡高清| 欧美一区不卡| 悠悠资源网久久精品| 久久午夜影院| 日韩欧美2区| 99精品视频精品精品视频| 国产乱人伦精品一区|