Java TDD简介–第1部分
歡迎來(lái)到測(cè)試驅(qū)動(dòng)開(kāi)發(fā) (TDD)系列的介紹。 我們將在TDD上下文中討論Java和JUnit ,但這只是工具。 本文的主要目的是使您全面了解TDD,而無(wú)論使用哪種編程語(yǔ)言和測(cè)試框架。
如果您在項(xiàng)目中不使用TDD,那么您要么很懶,要么就是根本不知道TDD的工作方式。 關(guān)于缺乏時(shí)間的借口不適用于這里。
關(guān)于這篇文章
在這篇文章中,我將解釋什么是TDD以及如何在Java中使用它。 在TDD中,單元測(cè)試應(yīng)放在哪個(gè)位置。 單元測(cè)試必須涵蓋的內(nèi)容。 最后,為了編寫(xiě)良好而有效的單元測(cè)試,需要遵循哪些原則。
如果您已經(jīng)了解Java中有關(guān)TDD的所有知識(shí),但是對(duì)示例和教程感興趣,那么我建議您跳過(guò)這一部分,繼續(xù)下一部分(它將在這一部分發(fā)布后的一周內(nèi)發(fā)布)。
什么是TDD?
如果有人要我用幾句話(huà)來(lái)解釋TDD,那么我說(shuō)TDD是功能實(shí)現(xiàn)之前的測(cè)試開(kāi)發(fā)。 您可以爭(zhēng)辯:很難測(cè)試尚不存在的事物。 肯特·貝克(Kent Beck)可能會(huì)為此一巴掌。
那怎么可能呢? 可以通過(guò)以下步驟進(jìn)行描述:
1.閱讀并了解特定功能的要求。
2.您開(kāi)發(fā)了一組測(cè)試功能的測(cè)試。 由于沒(méi)有功能實(shí)施,所有測(cè)試均為紅色。
3.開(kāi)發(fā)功能,直到所有測(cè)試變?yōu)榫G色。 4.重構(gòu)代碼。
TDD需要不同的思維方式,因此,為了根據(jù)它開(kāi)始工作,您需要忘記以前開(kāi)發(fā)代碼的方式。 這個(gè)過(guò)程很難。 如果您不知道如何編寫(xiě)單元測(cè)試,那就更難了。 但這是值得的。
使用TDD進(jìn)行開(kāi)發(fā)具有寶貴的優(yōu)勢(shì):
1.您對(duì)實(shí)現(xiàn)的功能有更好的了解。
2.您具有功能完整性的可靠指標(biāo)。
3.代碼包含測(cè)試,并且被修復(fù)或新功能破壞的可能性較小。
這些優(yōu)勢(shì)的代價(jià)是很高的–與切換到新的開(kāi)發(fā)方式有關(guān)的不便以及您花費(fèi)在開(kāi)發(fā)每個(gè)新功能上的時(shí)間。 這是質(zhì)量的代價(jià)。
這就是TDD的工作方式–編寫(xiě)紅色的單元測(cè)試,開(kāi)始實(shí)現(xiàn)功能,使測(cè)試變?yōu)榫G色,執(zhí)行代碼重構(gòu)。
TDD中單元測(cè)試的位置
由于單元測(cè)試是測(cè)試自動(dòng)化金字塔中最小的元素,因此TDD基于它們。 借助單元測(cè)試,我們可以檢查任何類(lèi)的業(yè)務(wù)邏輯。 如果您知道如何做,則編寫(xiě)單元測(cè)試很容易。 那么,您需要使用單元測(cè)試進(jìn)行測(cè)試的內(nèi)容以及該怎么做呢? 您知道這些問(wèn)題的答案嗎? 我將嘗試以簡(jiǎn)潔的形式說(shuō)明答案。
單元測(cè)試應(yīng)盡可能小。 不,不不要考慮這一點(diǎn),因?yàn)橐豁?xiàng)測(cè)試僅適用于一種方法。 當(dāng)然,這種情況也是可能的。 但通常,一個(gè)單元測(cè)試意味著調(diào)用多種方法。 這稱(chēng)為行為測(cè)試。
讓我們考慮Account類(lèi):
public class Account {private String id = RandomStringUtils.randomAlphanumeric(6);private boolean status;private String zone;private BigDecimal amount;public Account() {status = true;zone = Zone.ZONE_1.name();amount = createBigDecimal(0.00);}public Account(boolean status, Zone zone, double amount) {this.status = status;this.zone = zone.name();this.amount = createBigDecimal(amount);}public enum Zone {ZONE_1, ZONE_2, ZONE_3}public static BigDecimal createBigDecimal(double total) {return new BigDecimal(total).setScale(2, BigDecimal.ROUND_HALF_UP);}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("id: ").append(getId()).append("\nstatus: ").append(getStatus()).append("\nzone: ").append(getZone()).append("\namount: ").append(getAmount());return sb.toString();}public String getId() {return id;}public boolean getStatus() {return status;}public void setStatus(boolean status) {this.status = status;}public String getZone() {return zone;}public void setZone(String zone) {this.zone = zone;}public BigDecimal getAmount() {return amount;}public void setAmount(BigDecimal amount) {if (amount.signum() < 0)throw new IllegalArgumentException("The amount does not accept negative values");this.amount = amount;} }該類(lèi)中有4種getter方法。 要特別注意它們。 如果我們?yōu)槊總€(gè)getter方法創(chuàng)建一個(gè)單獨(dú)的單元測(cè)試,則會(huì)得到太多的冗余代碼行。 可以通過(guò)行為測(cè)試來(lái)處理這種情況。 想象一下,我們需要使用其構(gòu)造函數(shù)之一來(lái)測(cè)試對(duì)象創(chuàng)建的正確性。 如何檢查對(duì)象是否按預(yù)期創(chuàng)建? 我們需要檢查每個(gè)字段的值。 因此,可以在這種情況下使用吸氣劑。
創(chuàng)建小型快速的單元測(cè)試 ,因?yàn)樗鼈儜?yīng)在每次提交到git存儲(chǔ)庫(kù)并將新的構(gòu)建提交到服務(wù)器之前執(zhí)行。 您可以考慮一個(gè)帶有實(shí)數(shù)的示例,以了解單元測(cè)試速度的重要性。 假設(shè)一個(gè)項(xiàng)目有1000個(gè)單元測(cè)試。 他們每個(gè)人都需要100毫秒。 結(jié)果,所有測(cè)試的運(yùn)行需要1分40秒。
實(shí)際上100ms對(duì)于單元測(cè)試來(lái)說(shuō)太長(zhǎng)了,因此您必須通過(guò)應(yīng)用不同的規(guī)則和技術(shù)來(lái)減少運(yùn)行時(shí)間,例如,不要在單元測(cè)試中執(zhí)行數(shù)據(jù)庫(kù)連接(根據(jù)定義,單元測(cè)試是隔離的)或在其中執(zhí)行昂貴的對(duì)象的初始化。 @Before塊。
為單元測(cè)試選擇好名字 。 測(cè)試的名稱(chēng)可以是您想要的任何名稱(chēng),但是它應(yīng)該代表測(cè)試進(jìn)行的驗(yàn)證。 例如,如果我需要測(cè)試Account類(lèi)的默認(rèn)構(gòu)造函數(shù),則將其命名為defaultConstructorTest 。 選擇測(cè)試名稱(chēng)的另一個(gè)有用建議是在命名測(cè)試之前編寫(xiě)測(cè)試邏輯。 在開(kāi)發(fā)測(cè)試時(shí),您會(huì)了解其中發(fā)生的情況,因此名稱(chēng)的組成變得更加容易。
單元測(cè)試應(yīng)該是可預(yù)測(cè)的 。 這是最明顯的要求。 我將在示例中進(jìn)行解釋。 為了檢查轉(zhuǎn)帳操作(需支付5%的費(fèi)用),您必須知道發(fā)送的金額以及輸出的金額。 此測(cè)試方案可以實(shí)現(xiàn)為發(fā)送100美元和接收95美元。
最后應(yīng)該對(duì)單元測(cè)試進(jìn)行細(xì)化 。 在每個(gè)測(cè)試中放置一個(gè)邏輯場(chǎng)景時(shí),您可以從測(cè)試中獲得有用的反饋。 并且在發(fā)生單個(gè)故障的情況下,您不會(huì)丟失有關(guān)其余功能的信息。
所有這些建議旨在改進(jìn)單元測(cè)試設(shè)計(jì)。 但是,您還需要了解一件事-測(cè)試設(shè)計(jì)技術(shù)的基礎(chǔ)知識(shí)。
測(cè)試設(shè)計(jì)技術(shù)基礎(chǔ)
沒(méi)有測(cè)試數(shù)據(jù)就不可能編寫(xiě)測(cè)試。 例如,當(dāng)您測(cè)試匯款系統(tǒng)時(shí),可以在匯款字段中設(shè)置一些金額。 在這種情況下,數(shù)量是測(cè)試數(shù)據(jù)。 那么您應(yīng)該選擇哪些值進(jìn)行測(cè)試? 為了回答這個(gè)問(wèn)題,我們需要經(jīng)歷最流行的測(cè)試設(shè)計(jì)技術(shù)。 測(cè)試設(shè)計(jì)技術(shù)的通用目的是簡(jiǎn)化測(cè)試數(shù)據(jù)的構(gòu)成。
首先,讓我們假設(shè)我們可以發(fā)送正整數(shù)的錢(qián)。 同樣,我們發(fā)送的郵件不能超過(guò)1000。這可以表示為:
0 < amount <= 1000; amount in integer我們所有的測(cè)試場(chǎng)景可以分為兩組:正面和負(fù)面場(chǎng)景。 第一個(gè)用于系統(tǒng)允許的測(cè)試數(shù)據(jù),并導(dǎo)致成功的結(jié)果。 第二種是所謂的“故障場(chǎng)景”,當(dāng)我們使用不適當(dāng)?shù)臄?shù)據(jù)與系統(tǒng)進(jìn)行交互時(shí)。
根據(jù)等價(jià)技術(shù)的類(lèi)別,我們可以從(0; 1000]范圍內(nèi)選擇一個(gè)隨機(jī)整數(shù)。設(shè)為500。由于系統(tǒng)適用于500,因此對(duì)于該范圍內(nèi)的所有整數(shù)均適用。有效值,也可以從范圍中選擇無(wú)效的輸入,可以是任何帶浮點(diǎn)的數(shù)字,例如125.50
然后我們必須參考邊界測(cè)試技術(shù) 。 根據(jù)它,我們必須從范圍的左側(cè)和右側(cè)選擇2個(gè)有效值。 在我們的例子中,我們以1為允許的最小正整數(shù),從右邊取1000。
下一步是在邊界上選擇2個(gè)無(wú)效值。 所以它是0和1001
因此,最后我們有6個(gè)值需要在單元測(cè)試中使用:
- (1,500,1000)–對(duì)于積極的情況
- (0,125.50,1001)–否定情況
摘要
在這篇文章中,我試圖解釋TDD的各個(gè)方面,并說(shuō)明在TDD中單元測(cè)試的重要性。 因此,我希望經(jīng)過(guò)如此詳盡和長(zhǎng)期的bla-bla理論,我們可以繼續(xù)實(shí)踐。 在下一篇文章中,我將演示如何在功能之前開(kāi)發(fā)測(cè)試。 我們將從文檔分析開(kāi)始,到代碼重構(gòu)結(jié)束,逐步進(jìn)行操作。
確保所有測(cè)試都是綠色的:)
翻譯自: https://www.javacodegeeks.com/2015/11/introduction-in-java-tdd-part-1.html
總結(jié)
以上是生活随笔為你收集整理的Java TDD简介–第1部分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 信达天御备案名(信达天御备案)
- 下一篇: 留尼汪岛属于哪个国家(留尼汪岛位于哪个洲