[軟體測試] 可測性分析和實踐

軟體測試中可測性一般是指對系統的可控性、可觀測性進行的評估,藉以反映系統設計、實現對測試的友好程度和相應的測試成本。可測性在測試階段會對系統的測試成本及關聯產品代碼的Patch次數產生重大影響。如何提高可測性成為軟體生命周期特別是前期(設計階段、coding階段)重要的一環。 本文帶領大家探索在實際項目中可測性相關的實戰經驗和對應的改進措施。

1 提高可測性的切入點

可測性的評估和改進最早開始於兩個階段:

a. 新項目的設計階段;

b. 已有項目新功能、新策略的提測階段。

這些是提高團隊設計的系統可測性和維持系統的設計高可測性的關鍵時間點。測試人員會利用各種場合、機會強化開發人員對於可測性的重視:

  1. 可測性的重要性每次設計討論會, 測試負責人必提醒大家在設計時注意可測性。否則設計出來的功能很可能需要進行重構。
  2. 可控性

每次晨會中的討論環節, 測試負責人會提醒模塊設計人員,設計的功能需要必要的外部控制、執行動作支持,否則QA無法精確控制過程及縮短測試耗時。

  1. 可觀測性每個功能進行測試設計階段,提前和開發人員溝通必要的功能,觀察結果集合可以系統外部獲得,錯誤結果可以被暴露而不是由內部邏輯完全消化。

那可控性和可觀測性又指哪些方面呢? 如何向開發人員合理的解釋可測性?

1.1 可控性

可控性指系統的狀態可受外部控制改變,而不是由內部模塊自發的完成。

舉個常見的例子:

A. 當某文件存在的時候,該模塊自動退出;

B. 當某pid.lock文件存在時,該模塊不能啟動,即使啟動也退出。

上面的狀態改變都是由一個外部的文件控制,擁有可控性。

說到這裡,問題來了,擁有可控性就萬事大吉了嗎? 請大家思考,你在實際項目過程中遇到過哪些有可控性但可控性較差的情況?

1.2 可觀測性

可觀測性指系統內的重要狀態、信息可通過一定手段由外部獲得。可觀測性不僅能觀測系統的輸出是否符合設計要求,還影響該系統是否可控。系統的必要狀態信息在系統測試控制階段起決定作用。沒有準確的狀態信息,測試人員無法判斷是否要進行下一步的控制變更。無法控制狀態變更,可控性又從何談起?

口說無憑,我們來看幾個作者實際項目中遇到的真實案例。

2 實戰分析

[1] 垃圾回收GC

垃圾回收GC模塊是常見的系統內模塊,相信很多測試人員遇到過下面場景或者類似場景:

開發人員終於在大吼一聲後宣布垃圾回收模塊完成,她的描述如下:

1) 該模塊定時自動觸發。觸發條件是每天晚上1點。

2) 該模塊觸發後每秒的處理量是N/s。是根據線上情況得到的經驗值,硬編碼到代碼中。

然後,就沒有然後了。

測試人員一陣迷茫,這就是全部的詢問換來的基本上是「它都是全自動的了,你還想要什麼的」表情。

因此這個新功能完成後的二次返工是必然的了。

首先,該模塊的可控性太差。測試環境不可以等待每天晚上1點這個時刻,必須有外部能影響這個」全自動「的手段提供。否則全量的系統測試用例回歸會被限定在固定測試時間點且無法調整和更改。

其次,該模塊的每秒處理量必須能更改到符合測試環境。測試環境基本上都是真實環境的放縮,特別是分散式系統等大規模應用。測試環境機器無論是數量還是類型都遠低於實際環境。這種條件下,參數的定量調整是必須要完成的輔助支持。

再次,沒有必要的描述如何判斷哪些文件/數據被GC掉了。無法觀測到執行結果集帶來的後果是無法精確的預期測試結果。

而相應的改進措施就是解決上面提到的問題。

[2] 系統內部狀態信息

為了保證存儲的數據高可用,分散式系統會採取多機存儲副本方法。即一個數據被N(>=2)個機器以一定的演算法存儲相同的數據副本。這個時候經常會遇到的問題:

a) 機器間的數據由於數據複製順序的不同,會有數據差異。a、b、c三台機器,a、b機器可能已完成一次數據的更新到最新數據版本data1,c還處於老版本data0.

b) 由於版本差異,內部必須維護副本revision的版本號以進行數據同步和異常處理。

這種情況, 好的設計原則上要保證多機副本的必要狀態信息被外部獲取。

A. 數據的副本分布信息、副本的revision版本號等需要提供介面獲得

B.由於機器宕機造成的副本分布變化要能夠及時反映和更新。(比如帶一定間隔周期的更新)

只有在這種必要信息被獲取的情況下,測試人員才能更好的掌握系統狀態並根據系統狀態進行清晰的測試結果預期。

[3] 參數的熱設定

參數的熱設定是經常碰到的問題。一個系統越複雜、可定製,它可設定的參數就越多。一個好的設計應該能熱設定其中的參數,然後執行重新載入動作。

舉個實際的例子, 下面的配置文件是一個系統的存儲節點配置文件截圖。該截圖僅展示了大約1/5的配置參數。

a. 如果參數不可重新熱載入,那麼測試用例執行過程中都必須進行進程的重啟。

進程的重啟勢必造成單個測試用例的時間拉長,複雜系統成百+的測試用例會造成總體測試時間的拉長。每個多消耗1-2分鐘,整體就是小時級別的時間消耗。這對Slow build或完整性測試集執行來說是個災難。可測性也比較差。

b. 參數不可熱載入會在系統運維期間失去熱調整參數的機會,可能導致系統的間斷性停服務。這對基礎服務來說是個噩夢,上層依賴於基礎服務的應用可能成百上千,停服的代價過於大。一些gdb強行attach進程進行等修改變數的臨時方法由於進程狀態的不確定性因素會帶來不小的風險。作者負責的項目曾出現gdb熱修改帶來集群主控節點宕機停集群的慘痛經歷。

參數的熱設定和載入雖然增加了一定的邏輯複雜度,但對比帶來的收益是值得付出並實踐的。

[4] 系統使用信息統計

系統使用信息的統計在如下方面特別重要:

1) 產品線運營數據,為產品運營、後續產品改進等環節提供一手資料

2) 運用系統、集群狀態信息監控以解決運維過程中發生的問題

3) 利用系統狀態信息進行內部運行狀態判定,以測試是否達預期

1和2雖然不直接涉及可測性,但測試人員在系統設計階段需要進行這方面的考慮以防止系統開發後期進行的功能性重構帶來測試整體架構重構。系統接近尾聲進行的功能性重構對測試人員來說是個非常頭疼的問題。測試用例依賴的統計信息等介面可能被大量使用,這類的更改帶來不小的用例調整、更正工作。

測試人員在信息統計的設計階段需要了解系統在現有的設計基礎上可能衍生的二期、三期甚至更後期的功能,以提前影響當前的功能設計,提高數據、介面、操作方面的可擴展性。為以後可能產生的新功能打好可測性基礎。少埋坑、多考慮場景適應性。

上面的場景是作者在實際測試項目中經常遇到的,因此抽取出來做個示例。實際的項目測試遇到的場景遠比這些複雜、多樣且不可預知。這個時候需要大家多思考場景,多根據已有的經驗進行防禦性準備。

那有沒有通用的提供可測性的方法呢?

3 提高可測性的通用方法

  1. 摒棄原有的開發人員只進行單純的代碼單元測試的觀念,讓開發人員也進行系統級測試。

作者在實踐過程中最推崇的方法就是此條。具體地說,開發人員進行的是系統級測試,禁止刷行覆蓋率型的單純函數覆蓋UT。由系統級介面或者功能來驅動整個測試過程。無法直接進行驅動的測試行為需要撰寫模擬器或者模擬模塊進行。

這樣開發人員會切身的感受到可控性和可觀測性的重要性。進而推動系統在這兩個方面的實現更易用和便於測試。由此而來的良性循環能讓系統整體可測性始終處於較好水平。

2. 測試人員深度了解被測系統,能夠在可測性出現問題的時候及時指出問題所在。

只有深度了解被測系統,詳細分析系統實現邏輯和代碼,做到可黑盒、可白盒測試的程度,才能提前預測可測性薄弱環節,提前預防這樣的事情發生。在可測性出現問題時,及時介入和提出建設性意見。在需要進行測試代碼植入以方便測試流暢進行等方面親自動手,協助開發人員解決問題。

可測性問題可能出現在系統的各個方面,但只要在系統生命周期的各個環節嚴格要求並輔以正確的方法,可測性問題就不會成為軟體測試中不可攻破的難關。各位朋友,你遇到過哪樣的可測性難題呢?如果讓你從設計階段就貫徹好的可測性要求並在整個流程中嚴格遵守,能否解決你的難題呢?


推薦閱讀:

A/B測試如何推動業務決策
閱讀 I 封閉測試在測試過程中的重要性
(Python)時序預測的七種方法
這裡是測試標題
性能測試必知的21件事:認清性能問題

TAG:軟體測試 | 測試 | 自動化測試 |