新聞中心
使用事先設(shè)計(jì)好的故障以確保你的代碼達(dá)到預(yù)期的結(jié)果,并遵循 .NET xUnit.net 測(cè)試框架來(lái)進(jìn)行測(cè)試。
創(chuàng)新互聯(lián)主營(yíng)信陽(yáng)網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,重慶APP開(kāi)發(fā),信陽(yáng)h5重慶小程序開(kāi)發(fā)公司搭建,信陽(yáng)網(wǎng)站營(yíng)銷(xiāo)推廣歡迎信陽(yáng)等地區(qū)企業(yè)咨詢(xún)
在變異測(cè)試是 TDD 的演變 一文中,我談到了迭代的力量。在可度量的測(cè)試中,迭代能夠保證找到問(wèn)題的解決方案。在那篇文章中,我們討論了迭代法幫助確定實(shí)現(xiàn)計(jì)算給定數(shù)字平方根的代碼。
我還演示了最有效的方法是找到可衡量的目標(biāo)或測(cè)試,然后以最佳猜測(cè)值開(kāi)始迭代。正如所預(yù)期的,第一次測(cè)試通常會(huì)失敗。因此,必須根據(jù)可衡量的目標(biāo)或測(cè)試對(duì)失敗的代碼進(jìn)行完善。根據(jù)運(yùn)行結(jié)果,對(duì)測(cè)試值進(jìn)行驗(yàn)證或進(jìn)一步加以完善。
在此模型中,學(xué)習(xí)獲得解決方案的唯一方法是反復(fù)失敗。這聽(tīng)起來(lái)有悖常理,但它確實(shí)有效。
按照這種分析,本文探討了在構(gòu)建包含某些依賴(lài)項(xiàng)的解決方案時(shí)使用 DevOps 的好方法。第一步是編寫(xiě)一個(gè)預(yù)期結(jié)果失敗的用例。
依賴(lài)性問(wèn)題是你不能依賴(lài)它們
正如邁克爾·尼加德Michael Nygard在《沒(méi)有終結(jié)狀態(tài)的架構(gòu)》中機(jī)智的表示的那樣,依賴(lài)問(wèn)題是一個(gè)很大的話題,最好留到另一篇文章中討論。在這里,你將會(huì)看到依賴(lài)項(xiàng)給項(xiàng)目帶來(lái)的一些潛在問(wèn)題,以及如何利用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)來(lái)避免這些陷阱。
首先,找到現(xiàn)實(shí)生活中的一個(gè)挑戰(zhàn),然后看看如何使用 TDD 解決它。
誰(shuí)把貓放出來(lái)?
一只貓站在屋頂
在敏捷開(kāi)發(fā)環(huán)境中,通過(guò)定義期望結(jié)果開(kāi)始構(gòu)建解決方案會(huì)很有幫助。通常,在 用戶(hù)故事user story 中描述期望結(jié)果:
我想使用我的家庭自動(dòng)化系統(tǒng)(HAS)來(lái)控制貓何時(shí)可以出門(mén),因?yàn)槲蚁氡WC它在夜間的安全。
現(xiàn)在你已經(jīng)有了一個(gè)用戶(hù)故事,你需要通過(guò)提供一些功能要求(即指定驗(yàn)收標(biāo)準(zhǔn))來(lái)對(duì)其進(jìn)行詳細(xì)說(shuō)明。 從偽代碼中描述的最簡(jiǎn)單的場(chǎng)景開(kāi)始:
場(chǎng)景 1:在夜間關(guān)閉貓門(mén)
- 用時(shí)鐘監(jiān)測(cè)到了晚上的時(shí)間
- 時(shí)鐘通知 HAS 系統(tǒng)
- HAS 關(guān)閉支持物聯(lián)網(wǎng)(IoT)的貓門(mén)
分解系統(tǒng)
開(kāi)始構(gòu)建之前,你需要將正在構(gòu)建的系統(tǒng)(HAS)進(jìn)行分解(分解為依賴(lài)項(xiàng))。你必須要做的第一件事是識(shí)別任何依賴(lài)項(xiàng)(如果幸運(yùn)的話,你的系統(tǒng)沒(méi)有依賴(lài)項(xiàng),這將會(huì)更容易,但是,這樣的系統(tǒng)可以說(shuō)不是非常有用)。
從上面的簡(jiǎn)單場(chǎng)景中,你可以看到所需的業(yè)務(wù)成果(自動(dòng)控制貓門(mén))取決于對(duì)夜間情況監(jiān)測(cè)。這種依賴(lài)性取決于時(shí)鐘。但是時(shí)鐘是無(wú)法區(qū)分白天和夜晚的。需要你來(lái)提供這種邏輯。
正在構(gòu)建的系統(tǒng)中的另一個(gè)依賴(lài)項(xiàng)是能夠自動(dòng)訪問(wèn)貓門(mén)并啟用或關(guān)閉它。該依賴(lài)項(xiàng)很可能取決于具有 IoT 功能的貓門(mén)提供的 API。
依賴(lài)管理面臨快速失敗
為了滿足依賴(lài)項(xiàng),我們將構(gòu)建確定當(dāng)前時(shí)間是白天還是晚上的邏輯。本著 TDD 的精神,我們將從一個(gè)小小的失敗開(kāi)始。
有關(guān)如何設(shè)置此練習(xí)所需的開(kāi)發(fā)環(huán)境和腳手架的詳細(xì)說(shuō)明,請(qǐng)參閱我的上一篇文章。我們將重用相同的 NET 環(huán)境和 xUnit.net 框架。
接下來(lái),創(chuàng)建一個(gè)名為 HAS(“家庭自動(dòng)化系統(tǒng)”)的新項(xiàng)目,創(chuàng)建一個(gè)名為 UnitTest1.cs 的文件。在該文件中,編寫(xiě)第一個(gè)失敗的單元測(cè)試。在此單元測(cè)試中,描述你的期望結(jié)果。例如,當(dāng)系統(tǒng)運(yùn)行時(shí),如果時(shí)間是晚上 7 點(diǎn),負(fù)責(zé)確定是白天還是夜晚的組件將返回值 Nighttime。
這是描述期望值的單元測(cè)試:
using System;using Xunit;namespace unittest{public class UnitTest1{DayOrNightUtility dayOrNightUtility = new DayOrNightUtility();[Fact]public void Given7pmReturnNighttime(){var expected = "Nighttime";var actual = dayOrNightUtility.GetDayOrNight();Assert.Equal(expected, actual);}}}
至此,你可能已經(jīng)熟悉了單元測(cè)試的結(jié)構(gòu)。快速?gòu)?fù)習(xí)一下:在此示例中,通過(guò)給單元測(cè)試一個(gè)描述性名稱(chēng)Given7pmReturnNighttime 來(lái)描述期望結(jié)果。然后,在單元測(cè)試的主體中,創(chuàng)建一個(gè)名為 expected 的變量,并為該變量指定期望值(在該示例中,值為 Nighttime)。然后,為實(shí)際值指定一個(gè) actual(在組件或服務(wù)處理一天中的時(shí)間之后可用)。
最后,通過(guò)斷言期望值和實(shí)際值是否相等來(lái)檢查是否滿足期望結(jié)果:Assert.Equal(expected, actual)。
你還可以在上面的列表中看到名為 dayOrNightUtility 的組件或服務(wù)。該模塊能夠接收消息GetDayOrNight,并且返回 string 類(lèi)型的值。
同樣,本著 TDD 的精神,描述的組件或服務(wù)還尚未構(gòu)建(僅為了后面說(shuō)明在此進(jìn)行描述)。構(gòu)建這些是由所描述的期望結(jié)果來(lái)驅(qū)動(dòng)的。
在 app 文件夾中創(chuàng)建一個(gè)新文件,并將其命名為 DayOrNightUtility.cs。將以下 C# 代碼添加到該文件中并保存:
using System;namespace app {public class DayOrNightUtility {public string GetDayOrNight() {string dayOrNight = "Undetermined";return dayOrNight;}}}
現(xiàn)在轉(zhuǎn)到命令行,將目錄更改為 unittests 文件夾,然后運(yùn)行:
[Xunit.net 00:00:02.33] unittest.UnitTest1.Given7pmReturnNighttime [FAIL]Failed unittest.UnitTest1.Given7pmReturnNighttime[...]
恭喜,你已經(jīng)完成了第一個(gè)失敗的單元測(cè)試。單元測(cè)試的期望結(jié)果是 DayOrNightUtility 方法返回字符串 Nighttime,但相反,它返回是 Undetermined。
修復(fù)失敗的單元測(cè)試
修復(fù)失敗的測(cè)試的一種快速而粗略的方法是將值 Undetermined 替換為值 Nighttime 并保存更改:
using System;namespace app {public class DayOrNightUtility {public string GetDayOrNight() {string dayOrNight = "Nighttime";return dayOrNight;}}}
現(xiàn)在運(yùn)行,成功了。
Starting test execution, please wait...Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.Test Run Successful.Test execution time: 2.6470 Seconds
但是,對(duì)值進(jìn)行硬編碼基本上是在作弊,最好為 DayOrNightUtility 方法賦予一些智能。修改 GetDayOrNight 方法以包括一些時(shí)間計(jì)算邏輯:
public string GetDayOrNight() {string dayOrNight = "Daylight";DateTime time = new DateTime();if(time.Hour < 7) {dayOrNight = "Nighttime";}return dayOrNight;}
該方法現(xiàn)在從系統(tǒng)獲取當(dāng)前時(shí)間,并與 Hour 比較,查看其是否小于上午 7 點(diǎn)。如果小于,則處理邏輯將 dayOrNight 字符串值從 Daylight 轉(zhuǎn)換為 Nighttime?,F(xiàn)在,單元測(cè)試通過(guò)。
測(cè)試驅(qū)動(dòng)解決方案的開(kāi)始
現(xiàn)在,我們已經(jīng)開(kāi)始了基本的單元測(cè)試,并為我們的時(shí)間依賴(lài)項(xiàng)提供了可行的解決方案。后面還有更多的測(cè)試案例需要執(zhí)行。
在下一篇文章中,我將演示如何對(duì)白天時(shí)間進(jìn)行測(cè)試以及如何在整個(gè)過(guò)程中利用故障。
當(dāng)前標(biāo)題:變異測(cè)試:如何利用故障?
標(biāo)題來(lái)源:http://m.fisionsoft.com.cn/article/dhdiccg.html


咨詢(xún)
建站咨詢(xún)

