官术网_书友最值得收藏!

2.3.3 不同級別的可測試性問題

2.3.3.1 代碼級別的可測試性

代碼級別的可測試性,通常用于度量單元測試的難易程度。對于一段代碼,如果需要依賴測試框架和Mock框架的高級特性,或奇技淫巧,才能完成測試,則意味著該代碼的可測試性較差。編寫具有良好可測試性的代碼并非易事,違反可測試性的反模式不勝枚舉。比如,無法Mock依賴的組件或服務(wù)、代碼中包含未決行為邏輯、濫用可變?nèi)肿兞俊E用靜態(tài)方法、使用復雜的繼承關(guān)系、高度耦合的代碼、I/O和計算不解耦,等等。而那些隨心所欲的注釋、莫名其妙的鏈接,如果再“下點毒”,測試人員不“吐血”才怪!

除編程技能外,良心、規(guī)范是確保代碼可測試性的基礎(chǔ)。為了便于理解代碼級別的可測試性,下面以“無法Mock依賴的組件或服務(wù)”為例進行說明。

上述Transaction類是經(jīng)過抽象簡化的一個電商系統(tǒng)交易類,用以記錄每筆訂單的交易情況,類中的execute()函數(shù)實現(xiàn)轉(zhuǎn)賬操作,將交易費用從買家轉(zhuǎn)入賣家,通過Execute()函數(shù)調(diào)用WalletRpcService RPC服務(wù)完成轉(zhuǎn)賬操作。對此,編寫如下測試代碼,通過提供參數(shù)調(diào)用Execute()函數(shù),實現(xiàn)上述轉(zhuǎn)賬服務(wù)測試。

該測試代碼提供參數(shù)調(diào)用Execute()函數(shù),但為了使得該測試能夠順利運行,需要部署WalletRpcService服務(wù),但搭建和維護成本較高,且需要確保將構(gòu)造的transaction數(shù)據(jù)發(fā)送給WalletRpcService服務(wù)之后,返回期望結(jié)果以完成不同路徑覆蓋。基于網(wǎng)絡(luò)的測試執(zhí)行,耗時較長,網(wǎng)絡(luò)中斷、超時以及WalletRpcService服務(wù)不可用等情況都會影響測試執(zhí)行,需要用Mock實現(xiàn)依賴解耦,即用一個“假”服務(wù)替換“真”服務(wù),模擬輸出所需數(shù)據(jù),以便控制測試執(zhí)行路徑。因此,構(gòu)建如下Mock,通過繼承WalletRpcService類,重寫moveMoney()函數(shù),就可以讓moveMoney()返回任意想要得到的數(shù)據(jù),而無須進行網(wǎng)絡(luò)通信。

接下來,如果用MockWalletRpcServiceOne和MockWalletRpcServiceTwo代替代碼中的WalletRpcService,就會發(fā)現(xiàn)WalletRpcService是在execute()函數(shù)中通過new方式創(chuàng)建,無法動態(tài)地對其替換,這就是典型的代碼測試性問題。

為了能夠有效地解決該問題,可通過依賴注入方式,對代碼進行適當重構(gòu),將WalletRpcService對象的創(chuàng)建反轉(zhuǎn)給上層邏輯,在外部創(chuàng)建完成之后,將其注入到Transaction類中。重構(gòu)后的測試代碼如下:

2.3.3.2 服務(wù)級別的可測試性

在服務(wù)級別,基于服務(wù)架構(gòu),可測試性包括接口設(shè)計文檔的詳細程度、接口設(shè)計的契約化程度、私有協(xié)議設(shè)計的詳細程度、服務(wù)內(nèi)部狀態(tài)的可控制性、服務(wù)運行的可隔離性、服務(wù)扇入扇出大小、服務(wù)資源占用的可觀測性、內(nèi)置測試(Built-In Test,BIT)的實現(xiàn)程度以及服務(wù)部署、服務(wù)配置信息獲取、測試數(shù)據(jù)構(gòu)造、服務(wù)輸出結(jié)果驗證、服務(wù)后向兼容性驗證、服務(wù)契約獲取與聚合、內(nèi)部異常模擬、外部異常模擬、服務(wù)調(diào)用鏈路追蹤等的難易程度。

2.3.3.3 業(yè)務(wù)需求級別的可測試性

業(yè)務(wù)需求級別的可測試性可劃分為人工及自動化測試的可測試性,通常包括登錄過程中的圖片或短信驗證碼、硬件U盾/USB Key、觸屏應(yīng)用的自動化測試設(shè)計、第三方系統(tǒng)的依賴與模擬、業(yè)務(wù)測試流量隔離、系統(tǒng)不確定性彈框、非回顯結(jié)果驗證、可測試性與安全性平衡、業(yè)務(wù)測試的分段執(zhí)行、業(yè)務(wù)測試數(shù)據(jù)構(gòu)造等典型場景。

主站蜘蛛池模板: 枣阳市| 砀山县| 吴川市| 湘乡市| 定州市| 莱州市| 景洪市| 顺平县| 漳平市| 贵州省| 兰坪| 秦皇岛市| 梨树县| 永川市| 资阳市| 尖扎县| 巴马| 清水县| 通渭县| 古蔺县| 韶山市| 开远市| 三门峡市| 郸城县| 凤城市| 阿拉尔市| 泽州县| 宾阳县| 邢台县| 唐海县| 林周县| 分宜县| 汉阴县| 韶关市| 玉田县| 乐陵市| 郎溪县| 西畴县| 台南市| 蕲春县| 奈曼旗|