1. 程式人生 > >[技術思考] 軟體可測性分析和實踐

[技術思考] 軟體可測性分析和實踐

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

1 提高可測性的切入點

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

a. 新專案的設計階段;

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

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

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

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

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

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

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

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

歡迎大家關注公號, 一起在技術領域互動和討