測試驅動開發(TDD)研究

      網友投稿 894 2025-03-31

      1??????【引言】

      測試驅動開發(TDD)是一種依靠超短開發周期理念而進行的軟件開發過程:

      將需求變成非常具體的測試用例,然后對代碼進行編寫改進,使測試通過。

      這與軟件開發中允許添加一些需求不關心的代碼的軟件開發理念是格格不入的。

      2??????【測試驅動開發(TDD)】

      美國軟件工程師肯特-貝克(Kent Beck)被認為是該技術的推動者和積極倡導者,他在2003年表示,TDD鼓勵簡單的設計,而簡單的設計會讓你對所開發的產品充滿信心。

      測試驅動開發與1999年開始的極限編程的測試第一的編程理念有些關聯,但是近年來,測試驅動開發本身引起了更多的關注。

      有的程序員還將這一概念推廣到改進和調試現有老舊技術代碼和代碼重構上。

      2.1????測試驅動開發的周期

      下面的周期來自《測試驅動開發》一書中的例子:

      2.1.1????添加一個測試

      在測試驅動的開發中,每一個新功能都要從寫一個測試開始。編寫一個測試,定義一個功能或改進一個功能的測試,應該非常簡潔。要編寫測試,開發人員必須清楚地了解功能的規范和需求。開發者可以通過用例和用戶案例故事來完成,覆蓋需求和異常情況,可以用任何適合軟件環境的測試框架來編寫測試。它可以是現有測試的修改版本。

      這是測試驅動開發與代碼寫完之后再寫單元測試的區別:

      測試驅動開發要求開發人員在寫代碼之前就把注意力放在需求上,這是一個微妙但重要的區別。

      2.1.2????添加完測試以后,運行所有測試,查看新測試是否失敗

      這是為了驗證測試工作是否正確:

      如果新測試可以通過測試,說明開發人員不需要添加新的功能代碼了,因為所需的功能已經存在了。

      新的測試一般會失敗,因為這是我們所預期的結果。

      這也增加了開發人員對新測試的信心。

      2.1.3????編寫代碼

      下一步,就是寫一些代碼讓測試通過。在這個階段寫出的新代碼并不完美,比如說,可能通過測試的方式并不完美。這都是可以接受的,因為我們會在步驟5中進行改進。

      這時,編寫代碼的唯一目的就是為了通過測試。程序員不能寫出超出測試檢查的功能之外的代碼。

      2.1.4????運行測試

      如果現在所有的測試用例都通過了,那么程序員可以確信新的代碼符合測試要求,不會破壞或降低任何現有的功能。如果不符合,則必須調整新代碼,直到符合為止。

      2.1.5????重構代碼

      在測試驅動的開發過程中,必須定期清理不斷增長的代碼庫。新的代碼可以從僅僅通過測試的目的轉移到更符合邏輯的思考上來。重復的代碼當然要被刪除。對象、類、模塊、變量和方法的名稱應該清楚地表示它們當前的目的和用途。

      隨著功能的增加,方法函數可能變長,對象可能變大。此時我們可以進行拆分,并對新的部分進行準確的命名,以提高可讀性和可維護性,這在軟件生命周期的后期會越來越有價值。

      繼承層次結構可能會被重新安排,使其更有邏輯性和幫助性,有一些公認的設計模式可以參考一下,對于重構和干凈的代碼,有具體的和一般的準則。

      通過在每個重構階段不斷地重新運行測試用例,開發人員可以確信這個過程不會改變任何現有的功能。

      刪除重復的概念是軟件設計的一個重要方面。?在這種情況下,它也適用于消除測試代碼和生產代碼之間的重復。?例如,為了使測試在步驟3中通過而在兩者中重復的模擬數字或字符串。

      2.1.6????重復上述步驟

      接下來就是重復上述5個步驟,從另一個新的測試開始,然后重復循環推進功能。步驟的大小應始終保持在較小的范圍內,每次測試之間盡量少做1到10次編輯。如果新代碼不能迅速滿足新測試,或者其他測試意外失敗,程序員應該撤銷或還原,而不是過度調試。

      這在持續集成中可以通過提供可恢復的一些檢查點來實現。

      在使用外部庫的時候,不要忽略自身需求,以至于只是對庫本身進行測試,除非想確定這個庫是不是有bug,或者說這個庫的功能不夠完善。那這種情況可能要放棄這類程序庫,或者自己研發。

      2.2????最佳做法

      2.2.1????測試結構

      測試用例的有效布局可以確保所有需要的操作都能完成,提高測試用例的可讀性,使執行流程更加順暢。一致的結構有助于建立一個自記錄的測試用例。一個常用的測試用例結構有(1)設置、(2)執行、(3)驗證、(4)清理。

      n??設置(Setup)。設置:將被測單元(UUT)或整個測試系統置于運行測試所需的狀態中。

      n??執行:觸發/驅動UUT執行目標行為,并捕獲所有輸出,如返回值和輸出參數等。這一步通常非常簡單。

      n??驗證:驗證。確保測試的結果是正確的。這些結果可能包括執行過程中捕獲的顯式輸出或UUT中的狀態變化。

      n??清理。將UUT或整個測試系統恢復到測試前的狀態。這種恢復允許在此測試之后立即執行另一個測試。

      使用測試驅動開發有很多需要注意的方面,例如?"keep it simple, stupid"(KISS)和?"You aren't gonna need it"(YAGNI)的原則。通過專注于只寫讓測試通過所需的代碼,設計往往可以比其他方法實現的設計更干凈、更清晰,在《測試驅動開發實例》(Test-Driven Development by Example)一書中,Kent Beck也提出了?"Fake it till you make it "的原則。

      為了實現某種高級設計概念,比如設計模式,要寫出生成該設計的測試。代碼可能會比目標模式更簡單,但仍然通過所有需要的測試。這在一開始可能會讓人不放心,但它的好處是讓開發者更專注于業務本身。

      2.2.2????先寫測試:

      測試應該寫在要測試的功能之前。這樣做有很多好處,它有助于確保應用程序的可測試性,因為開發人員必須從一開始就考慮如何測試應用程序,而不是事后再添加。它還能確保每個功能的測試都能被編寫出來。此外,先寫測試可以使開發人員更深入、更早地了解產品需求,確保測試代碼的有效性,并保持對軟件質量的持續關注。

      在編寫功能優先的代碼時,開發人員和團隊會有一種傾向,就是把開發人員不停的推到下一個功能上,最后甚至完全忽略了測試。

      第一個TDD測試一開始可能甚至不能編譯,因為它所需要的類和方法還不存在。然而,第一個測試可作為需求實現的第一步。

      每個測試用例最初都會失敗。這樣可以確保測試真正的可以起作用,并能捕捉到錯誤。一旦成功,就實現了內部的功能代碼。這就形成了?"測試驅動開發的口頭禪",即?"紅/綠/重構",紅色表示失敗,綠色表示通過。測試驅動開發不斷地重復著添加失敗的測試用例、修復代碼讓測試用例通過、重構的步驟。在每個階段都存在預期的測試結果,這強化了開發人員對代碼的預期效果,增強了信心,從而提高了工作效率。

      2.2.3????要保證工作單元足夠的小。

      對于TDD來說,最常見的是將單元定義為一個類,或一組相關的功能,通常被稱為模塊。保持工作單元相對較小,好處包括:

      n??減少調試工作?-?當測試失敗被檢測到時,使用較小的工作單元有助于追蹤錯誤。

      n??測試即文檔--小的測試用例更容易閱讀和理解。

      測試驅動開發的先進實踐可以推動驗收測試驅動開發(ATDD)和用例規范化。

      其中客戶指定的需求標準被自動化地轉為驗收測試,然后推動傳統的單元測試驅動開發(UTDD)過程。

      這個過程確保客戶有一個自動化的機制來決定軟件是否滿足他們的需求。

      有了UTDD,開發團隊就有了一個特定的目標--驗收測試,從而讓他們持續關注每個用戶案例故事中真正想要的東西。

      2.2.4????實踐中的最佳做法

      可以參考的一些最佳做法是:

      n??將常見的設置和拆分邏輯分離成測試用例所使用的測試支持服務;

      n??讓每個測試用例只關注驗證其測試所需的結果;

      n??并設計與時間相關的測試,以允許在非實時操作系統中的可能存在的執行偏差。通常的做法是允許5%-10%的延遲執行余量,這樣可以減少測試執行中可能出現的假失敗結果;

      n??同時,建議以對待生產代碼相同的尊重態度來對待測試代碼,測試代碼案例必須都能正常工作,而且持之以恒,保證可讀可維護;

      測試驅動開發(TDD)研究

      n??團隊可以聚在一起,并對測試編寫和測試運行進行回顧,分享有效的技巧,摒棄壞的習慣。

      2.2.5????應避免的做法

      n??讓測試用例依賴于從之前執行的測試用例中操縱的系統狀態(也就是說,你應該總是從一個已知的、預先配置好的狀態開始進行單元測試)。

      n??測試用例之間的依賴關系。一個測試用例之間相互依賴的測試套件是脆弱而復雜的。執行順序不應該被推定。

      n??相互依賴的測試。相互依賴的測試會導致級聯的假失敗。即使UUT中不存在實際的故障,早期測試用例中的故障也會破壞后面的測試用例,增加分析失誤和調試工作。

      n??測試精確的執行時序或性能。

      n??構建?"全能系統"。隨著時間的推移,這種系統維護成本會越來越高高,也會更脆弱。這種非常常見的錯誤是致命的,危險的,因為它造成了整個項目復雜度無節制的增長。

      n??測試代碼實現的微小細節。

      n??測試的緩慢運行。

      2.3????測試驅動的工作

      測試驅動開發除了應用在軟件開發團隊中,還可以用在產品和服務團隊中,與TDD類似,非軟件團隊在工作開始前對工作的每個方面進行質量控制(QC)檢查(通常是手動測試而不是自動測試)。然后,這些QC檢查被用來為設計提供信息,并驗證相關結果。在TDD周期的基礎上少做改動形成了如下六個步驟:

      1.???????以?"添加檢查?"取代?"添加測試"。

      2.???????以?"運行所有檢查?"取代?"運行所有測試"

      3.???????用?"做工作?"代替?"寫一些代碼"

      4.???????以?"運行所有檢查?"取代?"運行測試"

      5.???????"清理工作?"取代了?"重構代碼"

      6.???????"重復"

      2.4????TDD和ATDD

      測試驅動開發與驗收測試驅動開發(ATDD)相關,但又不同于驗收測試驅動開發,TDD主要是開發者的工具,幫助開發者創建一個寫得很好的代碼單元(函數、類或模塊),正確地執行一組操作。ATDD是客戶、開發人員和測試人員之間的溝通工具,以確保需求的定義良好。TDD要求測試自動化。ATDD不需要,盡管自動化有助于回歸測試。TDD中使用的測試通常可以從ATDD測試中派生出來,因為代碼單元實現了需求的某些部分。ATDD測試是客戶可以閱讀的。TDD測試不需要。

      2.5????TDD與BDD

      BDD(行為驅動開發)結合了來自TDD和ATDD的實踐,它也是先寫測試,但更側重于描述行為的測試,而不是功能單元的測試。諸如JBehave、Cucumber、Mspec和Specflow等工具提供了共識語法,允許產品所有者、開發人員和測試工程師一起定義共識行為,然后將其轉化為自動測試。

      2.6????代碼可見性

      自然的,測試套件的代碼必須能夠訪問它正在測試的代碼。另一方面,常規的設計原則,如信息隱藏、封裝和其他關注點的分離等都不應該受到影響。因此,用于TDD的單元測試代碼通常是在同一個項目或模塊中編寫的。

      在面向對象設計中,這仍然不能提供對私有數據和方法的訪問。因此,單元測試可能需要額外的工作。在Java和其他語言中,開發者可以使用反射來訪問私有字段和方法,另外,也可以使用一個內部類來容納單元測試,這樣他們就能使用外部類的成員和屬性。在.NET框架和其他一些編程語言中,可以使用部分類來暴露私有的方法和數據供測試訪問。

      重要的是,這樣的測試實踐不應該保留在生產代碼中。

      在C語言和其他語言中,編譯器指令如#if DEBUG ..... #endif等指令可以放在這樣的附加類以及所有其他測試相關的代碼周圍,以防止它們被編譯到發布的代碼中。這就意味著發布的代碼與單元測試過的代碼并不完全相同。在最終發布的代碼中定期運行較少但更全面的端到端集成測試,以便可以確保生產代碼不存在依賴測試環境的情況。

      在TDD的實踐者中,存在有一些爭論,即測試私有方法和數據是否明智。

      有些人認為,私有成員只是一個實現細節,可能會發生變化,應該在不破壞測試數量的情況下允許其發生變化。因此,對任何類通過其公有接口或子類接口進行測試就應該足夠了,有些語言稱其為?"protected "接口。"

      另一些人說,功能的關鍵部分可能在私有方法中實現,直接測試它們提供了更小、更直接的單元測試的優勢。

      2.7????TDD軟件

      在TDD中,有很多測試框架和工具是很有用的。

      2.7.1????xUnit Frameworks

      開發者可以使用計算機輔助測試框架,通常統稱為xUnit(源自1998年創建的SUnit),來創建和自動運行測試用例。這些能力對于自動化來說至關重要,因為它們將執行驗證的負擔從獨立的后處理活動轉移到了測試執行中。這些測試框架提供的執行框架允許自動執行所有系統測試用例或各種子集以及其他功能。

      2.7.2????TAP Results

      該測試框架可以辨識1987年創建的語言無關測試協議中的單元測試輸出。

      2.8????模擬和集成測試

      單元測試之所以成為單元測試,是因為每一個測試只測試一個功能單元的代碼。一個復雜的模塊可能有一千個單元測試,而一個簡單的模塊可能只有十個。用于TDD的單元測試不應該跨越程序中的進程邊界,更不用說網絡連接了。這樣做會引入延遲,使測試運行緩慢,使開發人員不愿意運行整個套件。引入對外部模塊或數據的依賴關系也會使單元測試變成集成測試。如果一個模塊在一連串相互關聯的模塊中出現了錯誤行為,那么就不那么容易立刻知道從哪里尋找故障原因了。

      當開發中的代碼依賴于數據庫、Web服務或其他任何外部進程或服務時,進行單元測試分離是必須的,這也是為了設計出更加模塊化、更容易測試的、更可復用的代碼,一下兩個步驟是必要的:

      1.???????每當設計中需要外部訪問時,應該定義一個接口,并定義可用的訪問方式。

      2.???????接口應該用兩種方式來實現,一種是真正訪問外部環境,另一種是模擬對象。模擬對象只需要在跟蹤日志中添加一條消息,比如?"對象已保存?"這樣的消息來表明這個接口調用的任務內容,并在此基礎上運行測試斷言來驗證行為是否正確。模擬對象的不同之處在于,它們本身就包含測試斷言,可以使測試失敗,例如,如果人的名字和其他數據與預期的不一樣,那么測試就會失敗。

      模擬對象方法,看起來是返回來自數據存儲或用戶的數據,這可以通過始終返回相同的、真實的數據來完成測試過程,而這些數據是測試可以依賴的。

      也可以使用預定義的故障數據模式,這樣就可以測試錯誤處理例程。在故障模式下,方法可能會返回一個無效、不完整或空的響應,也可能拋出一個異常。

      2.8.1????數據存儲以外的模擬服務也可能在TDD中使用:

      模擬的加密服務可能實際上并沒有對傳遞的數據進行加密;

      模擬的隨機數服務可能總是返回1;

      模擬實現是通過依賴注入使用。

      測試替身(Test Double)是一種特別針對某些測試的能力,它可以替代UUT所依賴的系統能力,它通常是類或函數。

      2.8.2????有兩個時間點可以將測試替身引入系統中:

      鏈接時間和執行時間。

      鏈接時間替代是指測試替身被編譯到加載模塊中,執行時,測試替身被執行來驗證測試。

      這種方法一般是在目標環境以外的環境中運行時使用,因為目標環境要求硬件級的代碼編譯時需要用替身來編譯。

      鏈接器替換的替代方法是運行時替換,即在測試用例執行過程中替換真實功能。這種替換通常是通過對已知功能指針的重新分配或對象替換來完成。

      測試替身有許多不同的類型,他們有不同的復雜度:

      n??Dummy - Dummy是測試替身的最簡單形式。它通過在需要的地方提供一個默認的返回值,這就方便了鏈接器的時間點的替換。

      n??Stub - ?stub為Dummy方式添加了簡單的邏輯,提供了不同的輸出。

      n??Spy -?間諜可以捕獲或者提供參數和狀態信息,使用測試代碼的訪問器以獲得更高級的狀態驗證。

      n??Mock - Mock是由單個測試用例指定的,用于驗證測試的特定行為,檢查參數值和調用順序。

      n??Simulator –仿真器(Simulator)是一個全面的組件,提供目標能力(要被替換的功能)的高保真近似。仿真器(Simulator)通常需要大量的額外開發工作。

      使用替身這種依賴注入的一個必然結果是,實際的數據庫或其他外部訪問代碼從未被TDD過程本身測試過。為了避免由此產生的錯誤,需要其他測試,將測試驅動的代碼與上面討論的接口的?"真實"實現實例化。這就是集成測試,與TDD單元測試分離。它們的數量較少,而且運行的頻率必然低于單元測試。

      盡管如此,它們仍然可以使用相同的測試框架來實現。

      可能改變存儲或數據庫的集成測試,即使任何測試失敗,在設計時也應始終認真考慮文件或數據庫的初始和最終狀態。這通常可以通過以下技術的一些組合來實現:

      n??TearDown方法,這是許多測試框架中不可或缺的。

      n??try....catch...finally異常處理結構。

      n??數據庫事務中,一個事務原子化地包括寫、讀和刪除操作。

      n??在運行任何測試之前,對數據庫進行?"快照"存取,并在每次測試后回滾到快照數據。這可以通過使用Ant或NAnt等框架或CruiseControl等連續集成系統自動完成。

      n??在測試前將數據庫初始化為清潔狀態,而不是在測試后進行清理。這可能與清理工作有關,因為在進行詳細的診斷之前刪除數據庫的最終狀態可能會使測試失敗的診斷變得困難。

      2.9????復雜系統的TDD

      在大型的、具有挑戰性的系統上進行TDD,需要一個模塊化的架構、定義好的組件和發布的接口,以及有規律的系統分層,并最大限度地提高平臺的獨立性。這些實踐可以提高應用功能的可測性,并促進構建和測試自動化的實施。

      2.9.1????確保設計可測

      復雜的系統的架構需要滿足一系列的要求。這些要求的一個關鍵點包括支持系統的完整和可以有效的測試。有效的模塊化設計可以開發出共享特征明顯的組件,這對TDD是至關重要的。

      n??高內聚確保每個單元提供一組相關的功能,并使這些功能的測試更容易維護。

      n??低耦合使每個單元都能有效地進行隔離測試。

      n??發布的接口限制了組件的訪問,并作為測試的接觸點,方便了測試的創建,確保了測試和生產單元配置之間的最高保真度。

      構建有效的模塊化架構的一個關鍵技術是場景建模,在這個建模過程中要構建一組序列圖,每個序列圖都集中在一個單一的系統級執行場景下。

      場景模型提供了一個很好的平臺,用于創建組件之間響應特定實踐的交互策略。

      每一個場景模型為每一個組件提供所需的服務或功能需求集,它還決定了這些組件和服務一起交互的順序。

      場景模型可以大大促進復雜系統的TDD測試系統的構建。

      2.9.2????管理大型團隊的測試

      在一個較大的系統中,組件質量差的情況因交互的復雜性而被放大。這種放大效應使得TDD的好處在大型項目中更好的展現出來。然而,測試系統復雜度本身就可能會成為一個問題,這會抵消測試系統可能帶來的好處。

      關鍵的初始步驟是認識到測試代碼也是重要的軟件開發功能,應該與生產代碼一樣進行認真的編寫和維護。

      在一個復雜系統中創建和管理測試軟件的架構,與核心產品架構一樣重要。測試驅動程序要與UUT、測試替身和單元測試框架協同工作。

      3??????優缺點

      3.1????帶來的好處

      2005年的一項研究發現,使用TDD意味著寫更多的測試,反過來,寫更多測試的程序員往往會更有生產力。當然,與代碼質量有關的推論,?與TDD和生產力之間的直接關聯性目前還沒有定論。

      根據在新項目上使用純TDD的程序員的體會,他們覺得很少有必要使用調試器。與版本控制系統配合使用,當測試意外失敗時,將代碼還原到最后一個可通過所有測試的版本,往往比調試更有效果。

      測試驅動的開發提供的不僅僅是簡單的正確性驗證,還可以推動程序的設計,當你關注測試用例時,就必須想象客戶機是如何使用該功能的。所以,程序員在實現功能之前,先關注接口,再關注實現。這是對約定設計的補充,因為它是通過測試用例而不是通過數學斷言或預設來約束代碼的。

      測試驅動開發提供了按需分配的機動作戰能力。它允許程序員專注于手頭的任務,因為第一目標是使測試通過。異常情況和錯誤處理在一開始不會考慮,而這些外在情況的測試是單獨進行的。測試驅動開發通過這種方式確保了所有寫好的代碼都至少有一個測試覆蓋。這讓編程團隊以及后續的用戶對代碼有了更大的信心。

      雖然由于單元測試代碼的原因,使用TDD確實需要比沒有TDD的時候需要更多的代碼,但是根據Müller和Padberg的一個模型,總的代碼實現時間可能會更短,大量的測試有助于限制代碼中的缺陷數量。測試的早期性和頻繁性有助于在開發周期的初期抓住問題,防止缺陷成為系統性的昂貴問題。在整個過程的早期階段消除缺陷通常可以避免項目后期冗長而繁瑣的調試。

      TDD可以帶來模塊化、靈活性、可擴展性更高的代碼。這種效果的產生往往是因為這種方法論要求開發人員將軟件的思維方式看作是可以獨立編寫和測試的小單元,并在之后整合在一起。這推動開發了更小、更高內聚的類、更松散的耦合和更干凈的接口。模擬對象設計模式的使用也有助于代碼的整體模塊化,因為這種模式要求寫出的代碼可以方便地在用于單元測試的模擬版本和用于部署的?"真實?"版本之間切換。

      自動化測試往往會覆蓋每一條代碼路徑。例如,對于一個TDD開發人員來說,如果要在現有的if語句中添加一個else分支,開發人員首先要寫一個失敗的測試用例來觸發這個分支的測試失敗。因此,TDD所產生的自動化測試往往非常徹底:它們會檢測到代碼行為中的任何意外變化。這可以檢測出在開發周期后期的一個改變意外地改變了其他功能的問題。

      Madeyski提供了關于TDD實踐比傳統的Test-Last方法或Test for correctness方法的優越性的經驗證據(這些證據就是對200多名開發人員進行的一系列的實驗室實驗的結果),證明了TDD實踐在對象之間的低耦合(CBO)方面的優越性。根據對所做實驗的分析,平均效果大小代表了中等偏上的效果,這是一個現實性的實踐發現。它表明由于TDD編程實踐使開發出來的軟件產品具有更好的模塊化(即更多的模塊化設計),更容易復用和測試,Madeyski也用分支覆蓋率(BC)和突變評分指標(MSI)來衡量TDD實踐對單元測試的影響,這兩個指標分別是衡量單元測試的徹底性和故障檢測有效性的指標。

      TDD對分支覆蓋率的影響大小為中等偏上,因此被認為是非常有效的方法。

      3.2????局限性

      3.2.1????無法做到100%的需求覆蓋

      在測試驅動開發里模式下,由于大量使用單元測試,在一些情況下,測試驅動開發無法做到100%的需求覆蓋,這類情況的例子有:用戶界面、與數據庫一起工作的程序,以及一些依賴特定網絡配置的程序。TDD鼓勵開發人員將最少的代碼放到這類模塊中,并將可測試的庫代碼中的邏輯最大化,使用模擬數據來表示外部的依賴。

      3.2.2????管理層可能會覺得編寫測試的時間被浪費

      管理部門的支持是必不可少的。如果沒有整個團隊相信測試驅動的開發會改善產品質量的化,管理層可能會覺得編寫測試的時間被浪費了。

      3.2.3????測試可能會與代碼一樣存在共同的盲點

      在測試驅動的開發環境中創建的單元測試通常是由編寫被測代碼的開發人員創建的。因此,測試可能會與代碼一樣存在共同的盲點。例如,如果開發人員沒有意識到某些輸入參數必須被檢查,那么很可能測試和代碼都不會驗證這些參數。又比如:如果開發人員誤解了他正在開發的模塊的需求,那么他編寫的代碼和單元測試都會出現同樣的錯誤。此時,即使測試通過了,實質的內容確實不正確的。

      3.2.4????虛假的安全感

      大量通過的單元測試可能會帶來一種虛假的安全感,從而減少額外的軟件測試活動,如集成測試和合規性測試等。

      3.2.5????測試成為項目維護開銷的一部分

      測試成為項目維護開銷的一部分。寫得不好的測試,例如包含硬編碼錯誤字符串的測試,本身就很容易失敗,而且維護成本很高。特別是對于脆弱的測試來說更是如此,定期產生虛假故障的測試有可能被忽略,這樣一來,當真正的故障發生時,就可能無法被發現。編寫測試的時候,可以通過重用錯誤字符串等方式來實現低維護成本,這應該是代碼重構階段的目標。

      3.2.6????編寫和維護過多的測試會花費時間

      編寫和維護過多的測試會花費時間。另外,一些靈活的模塊本身測試數量有限,隨時可能會接受新的需求,而很多時候并不需要改變測試。基于這些原因,通過添加針對極端條件或小樣本數據進行的內容測試,比起寫一套高度詳細的測試更容易。

      3.2.7????可能出現無法發現的漏洞

      在反復的TDD周期中所達到的覆蓋率和測試水平,是在長期的實踐中得來的,不可能在短期內重現這種效果。因此,隨著時間的推移,那些原始的、或者說早期的測試會變得越來越珍貴。?如果出現問題,不要拖,盡快盡早的修復。另外,如果出現了糟糕的架構,糟糕的設計,或者是糟糕的測試策略,致使后期的改動導致大量的如幾十個現有的測試失敗的話,就必須要對這些測試進行單獨修復。不能僅僅刪除、禁用或草率地改變它們,那樣做會導致測試覆蓋率的降低,可能出現無法發現的漏洞。

      4??????參考

      http://agiledata.org/essays/tdd.html

      https://www.guru99.com/test-driven-development.html

      https://medium.com/javascript-scene/testing-software-what-is-tdd-459b2145405c

      https://medium.com/javascript-scene/testing-software-what-is-tdd-459b2145405c

      https://www.freecodecamp.org/news/test-driven-development-what-it-is-and-what-it-is-not-41fa6bca02a2/

      自動化測試

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何將批注顯示“已解決”?(批注無法顯示怎么辦)
      下一篇:Excel如何使用高亮重復項 Excel高亮重復項使用方法
      相關文章
      亚洲成亚洲乱码一二三四区软件| 亚洲欧洲日产国码www| 亚洲一区中文字幕久久| 午夜在线亚洲男人午在线| 久久精品亚洲精品国产色婷| 亚洲av高清在线观看一区二区| 亚洲一区免费在线观看| 亚洲一区二区无码偷拍| 亚洲一级片内射网站在线观看| 亚洲久本草在线中文字幕| 亚洲国产精品专区在线观看| 亚洲午夜电影在线观看高清| 亚洲av乱码一区二区三区| 婷婷久久久亚洲欧洲日产国码AV| 亚洲视频在线视频| 久久精品国产亚洲av水果派| 亚洲AV无码一区二区三区DV | 亚洲一区综合在线播放| 亚洲VA中文字幕不卡无码| 亚洲成人午夜在线| 久久亚洲AV成人无码国产| 亚洲成人福利在线观看| 亚洲一区二区三区乱码在线欧洲| 亚洲人成网站色在线观看| 亚洲Av永久无码精品一区二区| 亚洲aⅴ天堂av天堂无码麻豆 | 亚洲黄色片在线观看| 亚洲国产亚洲片在线观看播放| 亚洲w码欧洲s码免费| 亚洲精品无码成人| 一本色道久久88综合亚洲精品高清| 亚洲日本韩国在线| 亚洲αv久久久噜噜噜噜噜| 亚洲专区先锋影音| 亚洲午夜一区二区三区| 国产精品无码亚洲精品2021| 久久亚洲精品无码播放| 亚洲v高清理论电影| 亚洲一区电影在线观看| 风间由美在线亚洲一区| 亚洲香蕉成人AV网站在线观看|