想作測試工程師,這7件事你必須先知道

摘要:寫代碼歸開發攻城獅,測試歸測試攻城獅,大部分狀況下雙方處於「紅藍對峙」狀態。

1、「開發者測試」 就是「開發者來測試」

開發者測試是現代軟件工程中很是重要的一環,敏捷開發、主幹開發這些先進的項目管理方法和流程都基於完善的開發者測試。當每月甚至每週都要交付一個版本時,不可能投入大量的測試工程師來進行大規模的系統級別測試,這時候就須要把整個測試金字塔中的絕大部分測試經過自動化來完成。
image.png編程

咱們今天談開發者測試,什麼是「開發者測試」? 我司有清晰的開發與測試之分。寫代碼歸開發攻城獅,測試歸測試攻城獅,大部分狀況下雙方處於「紅藍對峙」狀態。這與我10多年前的研發團隊情況很是類似。而如今的軟件工程,專職的「測試攻城獅」很是少,不少公司開發測試比例大於10:1,甚至一些部門沒有測試攻城獅一說。 而測試攻城獅的角色再也不是手動跑測試用例的「苦力」,而是管理產品的測試系統,對產品測試進行規劃、分析概括功能測試思惟導圖、設計測試用例及帶領研發團隊進行測試工做,更像一位「測試專家/測試教練」。舉個簡單的例子,我以前作的產品是在線視頻會議協做產品。咱們天天的線上例會就是用本身作的產品,並且會使用本身開發的新功能測試站點來開「站會」。除了花少許的時間作dialy update,而後就是測試專家帶領團隊(包括PO、架構師、SM、Dev)按照計劃來進行集中(半個小時)的測試。因此說「開發者測試」就是「開發者來測試」,而咱們傳統的衆多測試工程師面臨三種出路:成長、轉型、淘汰。「測試專家」在項目中的話語權也很高,我以前的公司使用主幹開發,有個「一進一出」的評審,團隊的這種類型的「測試專家」有一票否決權。甚至在公司有PE級別的測試專家(至關於我司20-21級的技術專家)。segmentfault

  • 一進:對於一個功能是否可以進入release branch,在release branch打開feature toggle進行發佈級別的測試。
  • 一出:在engineer release時,該功能質量合格,容許feature toggle進入產線。

2、沒有什麼測試不能夠「自動化測試」

回到測試金字塔,從測試的"開發成本"、「執行成本」、「測試覆蓋率」、「問題定位」四個維度來看,基於代碼級別的白盒測試是及其重要的。
image.png架構

  • 開發成本: 實現測試用例的成本。
  • 執行成本:運行一次測試用例的成本。
  • 測試覆蓋率:咱們一般所說的line coverage和branch coverage
  • 問題定位:測試出現問題,定位問題的效率

經過測試金字塔及其四個測試維度評估,咱們能夠得出:框架

  • 儘量地多作Low Level Test :由於他們的執行速度相較於上層的幾個測試類型來講快不少且相對穩定,能夠一天屢次執行。通常來講,LLT灰作到持續集成構建任務中去,甚至在MR中執行,保障進入代碼倉庫的代碼質量。
  • 在自動化保障的狀況下,執行必定規模的IT、ST、UI Test:由於他們的執行速度較慢,環境依賴較多,測試先對不穩定。一般在夜裏執行一次,階段性的檢查代碼質量,反饋代碼問題。
  • 儘量地少作大規模的手動測試:由於他們的執行速度相較LLT且不夠穩定,人力成本較高,也沒法作到一天屢次執行,每次執行都要等好久才能得到反饋結果。可是,他們更貼近真實用戶場景,因此要確保必定週期內或者關鍵節點時間執行如下這幾個測試以確保軟件質量。

如今不少公司已經迭代發佈的週期愈來愈短,甚至作到了2周。手動測試顯然沒法適應這種開發模式,而把手動測試的用例經過各類技術方案自動化是惟一途徑。代碼層面,從底層業務代碼到UI代碼,只要架構設計合理,都是能夠作UT。最頂層的UI交互測試,測試用例也是能夠自動化運行(大部分UI框架均可以經過accessibility的接口進行UI自動化測試),試想連我們手機硬件均可以自動化測試「摔手機」這種極端測試,軟件有啥作不到?至少有些業界技術大牛公司的某些產品,從代碼提交Merge Request,到產品上產線是能夠以天來計算的。這種產品的測試是不會也不可能經過手工測試來完成的。函數

3、開發者測試」利在當下「,」贏得將來「

不少人都認爲底層的開發者測試,花了大量的時間,寫了大量的代碼,而後來保證功能的正確性,可是每次代碼功能或者結構的的變動都要修改測試代碼。我手動調試和驗證效率更高。的確經過UT,API測試來調試代碼與本身手動運行調試區別不大,可是經過開發者測試對代碼進行調試,從而保證當前項目迭代的質量;可是其更重要的做用不是這個。單元測試

咱們在bug分類中有這樣一些名詞 : Build Regression Bug, Release Regression Bug。測試

  • Build Regression Bug : 開發中一樣的功能在新版本出現一個bug,可是在以前的版本沒有這個問題,咱們叫作Build Regression Bug.
  • Release Regression Bug : 產線上一樣的功能在新版本出現一個bug,可是在以前的版本沒有這個問題,咱們叫作Release Regression Bug.

咱們每次commit到產品中的代碼,沒有人能夠保證其100%不會出現問題,在敏捷開發的這種快速迭代下,不太可能進行全功能的手動測試,因此開發者測試,特別是底層的UT、API測試、集成測試,可以很容易的識別發現這類問題。因此說開發者測試」利在當下「,」贏得將來「。ui

4、TDD不是必須先寫測試代碼

對於TDD,你們的認知是先寫測試代碼,再在寫實現代碼,這個說法對也不對。概念上沒錯,可是若是嚴格這樣作,效率未必最高,這也是TDD很難推廣的緣由之一。咱們把編碼實現分紅3個部分:實現代碼、測試代碼、調試代碼。按照TDD的概念時先寫測試代碼、而後編碼,最後調試。咱們一般在代碼實現時,一開始不大可能考慮的很是清晰,把接口定義的徹底準確,若是嚴格按照測試、編碼、調試來作,測試代碼要隨着編碼頻繁修改。 固然這自己不是什麼大問題,在實際執行過程當中,不少人習慣先搭好代碼框架、測試框架,而後在編碼,測試。等測試完成後在進行調試。因此從華爲灰度管理的角度上來講,只要單元測試在調試以前,均可以稱做TDD開發模式。BTW,固然如今開始流行BDD,這裏想說的是若是連我說的TDD都作不到的團隊,就不要考慮BDD了。編碼

(Behavior-Driven Development:BDD將TDD的通常技術和原理與領域驅動設計(DDD)的想法相結合。 BDD是一個設計活動,您能夠根據預期行爲逐步構建功能塊。 BDD的重點是軟件開發過程當中使用的語言和交互。 行爲驅動的開發人員使用他們的母語與領域驅動設計的語言相結合來描述他們的代碼的目的和好處。 使用BDD的團隊應該可以以用戶故事的形式提供大量的「功能文檔」,並增長可執行場景或示例。 BDD一般有助於領域專家理解實現而不是暴露代碼級別測試。它一般以GWT格式定義:GIVEN WHEN&THEN。)spa

5、UT覆蓋率100%真的很很差

於單元測試,咱們都會關注一個指標「覆蓋率」。無論模塊、函數、行、分支覆蓋率,必需要有必定比例的覆蓋率。可是每一項你都作到了100%,那麼會給你打「差評」。不是說你作到很差(這裏不談是否是用了正確的方式),而是成本和性價比問題。以最難達到的分支覆蓋率(branch coverage),若是要作到100%的覆蓋率,有些內存分配或者容錯保護的分支都必須測試到,那麼你的測試用例考慮要翻倍,可是並無帶來的相應價值。甚至一些代碼條件分支在程序運行的生命週期內都沒有被執行過。

  • 模塊覆蓋率:業務模塊代碼經過UT,架構模塊代碼經過IT;就從UT的覆蓋率的角度上去看,不須要去測試架構代碼。
  • 函數覆蓋率:不要爲一些無任何邏輯的代碼去寫UT。好比咱們有些函數就是get/set一個屬性,內部實現就用一個變量來賦值保存。這種函數寫UT就是爲了覆蓋率而寫,沒有任何真正的意義。
  • 行覆蓋率:一般來看平局80%上下的行覆蓋率是一個合理的指標,有些能夠爲0%,而有些須要100%,若是所有代碼都超過90%,其成本較高,效率較低,不建議這樣作。
  • 分支覆蓋率:越複雜的業務邏輯,越要寫更多的測試用例來覆蓋,而一些內存分配出錯邏輯判斷能夠不須要測試。

6、用測試來驅動架構和代碼質量

這裏談測試驅動架構和代碼質量,主要說的是讓代碼具有完善的可測試性,什麼是代碼的可測試性?簡單的說就是類與類之間,模塊與模塊關係解耦,類與類,模塊與模塊經過接口編程。依賴的接口經過被動注入式傳入,而不是主動獲取式。對於程序正常運行時,所傳入的接口參數是真實的業務對象,而作測試時,能夠傳入fake的模擬實現。固然不是全部的依賴模塊都這樣作,一些與業務無關的Utility Library,或者一些特定的數據對象實現,能夠直接調用。

這裏咱們講到了fake與mock,關於Test Doubles,基本上的概念以下,具體每種表明什麼意義,你們能夠自行上網搜索

  • 虛擬對象(dummy)
  • 存根(stub)
  • 間諜(spy)
  • 模擬對象(mock)
  • 僞對象(fake)
    image.png

當前我司你們在作開發者測試時,基本上都在用Mock Object(實際上在用的過程當中,不少是在用入參返回值控制的Stub)。拋開概念上的問題,雖然經過Mock的方式也是能夠測試代碼,可是實際上用Mock基本上意味着咱們的代碼關聯性較強,模塊顯示依賴較重,模塊移植性較差,特別是C語言編程這種問題特別多。以致於如今不少模塊根本沒法開展單元測試,更多的是在作集成測試。

爲何會出現這種狀況? 咱們的高級別的架構師更多的在考慮系統級別的架構設計,把系統模塊,各個應用之間的關係梳理的很是清晰,一般狀況下,高級別的架構師能夠把系統模塊或應用之間的關係設計的較爲合理。然而到了具體的應用業務內部的設計與實現,交給了低級別的架構師來完成。實際上這些模塊內部的代碼量並不小,不少都是幾十萬行甚至上百萬行的代碼量。這時候架構師的水平決定了代碼的Clean Code質量。我司目前代碼上的問題不少不是系統架構的問題,而是具體業務實現中,缺乏嚴格的要求和合理的架構設計。若是在應用級別有一套架構方案來規範,那麼至少在模塊的接口以及模塊與模塊以前的交互上也能達到和系統設計同樣較爲清晰合理。那麼不肯定的部分就時每一個子模塊內部幾千上萬行的代碼部分。

之因此提出用測試驅動架構和代碼質量,當給測試提出一個很高的標準時,你們不得不從架構上去解決測試的問題,當測試的問題解決時,Clean Code L3天然而然就達到了。

7、從「我要寫測試依賴代碼」到「我要寫測試依賴代碼」

這句話看着很奇怪,其實是從根本上去解決單元測試的根本方法。 模塊之間有依賴,無論是經過Mock仍是Fake的方法,無論架構上如何合理,這種依賴是不能消除的,咱們作到更多的是合理的設計讓依賴與模塊解耦。第一個「我要寫測試依賴代碼」,指的是當我實現個人模塊時,我要寫測試代碼來測試。而然我要考的是如何寫個人測試依賴。而第二個「我要寫測試依賴代碼」指的是,當我實現個人代碼時,我要考慮的是依賴個人模塊在測試時,對於個人依賴該怎麼解決,"我要寫測試依賴代碼」(就是我說的fake對象與實現)來幫助依賴個人模塊解決測試依賴問題。

  • 思惟轉變、測試驅動:開發一個模塊,不要先考慮怎麼測試本身,先考慮若是別人依賴我,我該怎麼讓別人更容易測試。模塊的提供者,不止要提供模塊代碼,還要提供一個可複用的Faked對象(調用驗證;返回值;參數驗證;參數處理;功能模擬等)。
  • 模塊代碼的編寫者實現本身的Fake實現,基本上大部分的代碼是由模塊編寫者來完成,同時這是一個可複用的Fake實現。模塊依賴方根據本身一些特殊的業務需求來添加本身的代碼。基本上遵循80/20原則。
  • 架構上依賴解耦,經過注入依賴的方式進行接口編程。開發者測試使用Fake來實現依賴。
  • 當編寫測試代碼時,全部依賴的接口、依賴的實現都基本完成,更多的關注些測試用例而不是測試依賴。

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索