軟件測試中可測性一般是指對系統(tǒng)的可控性、可觀測性進行的評估,借以反映系統(tǒng)設(shè)計、實現(xiàn)對測試的友好程度和相應(yīng)的測試成本??蓽y性在測試階段會對系統(tǒng)的測試成本及關(guān)聯(lián)產(chǎn)品代碼的Patch次數(shù)產(chǎn)生重大影響。如何提高可測性成為軟件生命周期特別是前期(設(shè)計階段、coding階段)重要的一環(huán)。 下面就讓匯智動力的老師來為大家講解一下實際項目中可測性相關(guān)的實戰(zhàn)經(jīng)驗和對應(yīng)的改進措施。

  1 提高可測性的切入點

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

  a. 新項目的設(shè)計階段;

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

  這些是提高團隊設(shè)計的系統(tǒng)可測性和維持系統(tǒng)的設(shè)計高可測性的關(guān)鍵時間點。測試人員會利用各種場合、機會強化開發(fā)人員對于可測性的重視:

  可測性的重要性每次設(shè)計討論會, 測試負責人必提醒大家在設(shè)計時注意可測性。否則設(shè)計出來的功能很可能需要進行重構(gòu)。

  可控性

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

  可觀測性每個功能進行測試設(shè)計階段,提前和開發(fā)人員溝通必要的功能,觀察結(jié)果集合可以系統(tǒng)外部獲得,錯誤結(jié)果可以被暴露而不是由內(nèi)部邏輯完全消化。

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

  1.1 可控性

  可控性指系統(tǒng)的狀態(tài)可受外部控制改變,而不是由內(nèi)部模塊自發(fā)的完成。

  舉個常見的例子:

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

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

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

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

  1.2 可觀測性

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

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

  2 實戰(zhàn)分析

  [1] 垃圾回收GC

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

  開發(fā)人員終于在大吼一聲后宣布垃圾回收模塊完成,她的描述如下:

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

  2) 該模塊觸發(fā)后每秒的處理量是N/s。是根據(jù)線上情況得到的經(jīng)驗值,硬編碼到代碼中。

  然后,就沒有然后了。

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

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

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

  其次,該模塊的每秒處理量必須能更改到符合測試環(huán)境。測試環(huán)境基本上都是真實環(huán)境的放縮,特別是分布式系統(tǒng)等大規(guī)模應(yīng)用。測試環(huán)境機器無論是數(shù)量還是類型都遠低于實際環(huán)境。這種條件下,參數(shù)的定量調(diào)整是必須要完成的輔助支持。

  再次,沒有必要的描述如何判斷哪些文件/數(shù)據(jù)被GC掉了。無法觀測到執(zhí)行結(jié)果集帶來的后果是無法精確的預(yù)期測試結(jié)果。

  而相應(yīng)的改進措施就是解決上面提到的問題。

  [2] 系統(tǒng)內(nèi)部狀態(tài)信息

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

  a) 機器間的數(shù)據(jù)由于數(shù)據(jù)復(fù)制順序的不同,會有數(shù)據(jù)差異。a、b、c三臺機器,a、b機器可能已完成一次數(shù)據(jù)的更新到最新數(shù)據(jù)版本data1,c還處于老版本data0.

  b) 由于版本差異,內(nèi)部必須維護副本revision的版本號以進行數(shù)據(jù)同步和異常處理。

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

  A. 數(shù)據(jù)的副本分布信息、副本的revision版本號等需要提供接口獲得

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

  只有在這種必要信息被獲取的情況下,測試人員才能更好的掌握系統(tǒng)狀態(tài)并根據(jù)系統(tǒng)狀態(tài)進行清晰的測試結(jié)果預(yù)期。

  [3] 參數(shù)的熱設(shè)定

  參數(shù)的熱設(shè)定是經(jīng)常碰到的問題。一個系統(tǒng)越復(fù)雜、可定制,它可設(shè)定的參數(shù)就越多。一個好的設(shè)計應(yīng)該能熱設(shè)定其中的參數(shù),然后執(zhí)行重新加載動作。

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

  a. 如果參數(shù)不可重新熱加載,那么測試用例執(zhí)行過程中都必須進行進程的重啟。

  進程的重啟勢必造成單個測試用例的時間拉長,復(fù)雜系統(tǒng)成百+的測試用例會造成總體測試時間的拉長。每個多消耗1-2分鐘,整體就是小時級別的時間消耗。這對Slow build或完整性測試集執(zhí)行來說是個災(zāi)難??蓽y性也比較差。

  b. 參數(shù)不可熱加載會在系統(tǒng)運維期間失去熱調(diào)整參數(shù)的機會,可能導致系統(tǒng)的間斷性停服務(wù)。這對基礎(chǔ)服務(wù)來說是個噩夢,上層依賴于基礎(chǔ)服務(wù)的應(yīng)用可能成百上千,停服的代價過于大。一些gdb強行attach進程進行等修改變量的臨時方法由于進程狀態(tài)的不確定性因素會帶來不小的風險。作者負責的項目曾出現(xiàn)gdb熱修改帶來集群主控節(jié)點宕機停集群的慘痛經(jīng)歷。

  參數(shù)的熱設(shè)定和加載雖然增加了一定的邏輯復(fù)雜度,但對比帶來的收益是值得付出并實踐的。

  [4] 系統(tǒng)使用信息統(tǒng)計

  系統(tǒng)使用信息的統(tǒng)計在如下方面特別重要:

  1) 產(chǎn)品線運營數(shù)據(jù),為產(chǎn)品運營、后續(xù)產(chǎn)品改進等環(huán)節(jié)提供一手資料

  2) 運用系統(tǒng)、集群狀態(tài)信息監(jiān)控以解決運維過程中發(fā)生的問題

  3) 利用系統(tǒng)狀態(tài)信息進行內(nèi)部運行狀態(tài)判定,以測試是否達預(yù)期

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

  測試人員在信息統(tǒng)計的設(shè)計階段需要了解系統(tǒng)在現(xiàn)有的設(shè)計基礎(chǔ)上可能衍生的二期、三期甚至更后期的功能,以提前影響當前的功能設(shè)計,提高數(shù)據(jù)、接口、操作方面的可擴展性。為以后可能產(chǎn)生的新功能打好可測性基礎(chǔ)。少埋坑、多考慮場景適應(yīng)性。

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

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

  3 提高可測性的通用方法

  摒棄原有的開發(fā)人員只進行單純的代碼單元測試的觀念,讓開發(fā)人員也進行系統(tǒng)級測試。作者在實踐過程中最推崇的方法就是此條。具體地說,開發(fā)人員進行的是系統(tǒng)級測試,禁止刷行覆蓋率型的單純函數(shù)覆蓋UT。由系統(tǒng)級接口或者功能來驅(qū)動整個測試過程。無法直接進行驅(qū)動的測試行為需要撰寫模擬器或者模擬模塊進行。這樣開發(fā)人員會切身的感受到可控性和可觀測性的重要性。進而推動系統(tǒng)在這兩個方面的實現(xiàn)更易用和便于測試。由此而來的良性循環(huán)能讓系統(tǒng)整體可測性始終處于較好水平。

  測試人員深度了解被測系統(tǒng),能夠在可測性出現(xiàn)問題的時候及時指出問題所在。只有深度了解被測系統(tǒng),詳細分析系統(tǒng)實現(xiàn)邏輯和代碼,做到可黑盒、可白盒測試的程度,才能提前預(yù)測可測性薄弱環(huán)節(jié),提前預(yù)防這樣的事情發(fā)生。在可測性出現(xiàn)問題時,及時介入和提出建設(shè)性意見。在需要進行測試代碼植入以方便測試流暢進行等方面親自動手,協(xié)助開發(fā)人員解決問題。

  可測性問題可能出現(xiàn)在系統(tǒng)的各個方面,但只要在系統(tǒng)生命周期的各個環(huán)節(jié)嚴格要求并輔以正確的方法,可測性問題就不會成為軟件測試中不可攻破的難關(guān)。各位朋友,你遇到過哪樣的可測性難題呢?如果讓你從設(shè)計階段就貫徹好的可測性要求并在整個流程中嚴格遵守,能否解決你的難題呢?