測試——《微服務設計》讀書筆記

一.測試象限(Brain Marick)html

      640?wx_fmt=png

 

二.測試金字塔(Mike Cohn)git

    640?wx_fmt=png

    

      1.單元測試github

      一般只測試一個函數或方法調用,經過TDD或者基於屬性而寫的測試就屬於這一類,在UnitTest中,咱們不會啓動服務,對且對外部文件和網絡鏈接的使用也頗有限,一般咱們須要大量的單元測試。安全

      640?wx_fmt=png

      單元測試是幫助開發人員,是面向技術而非業務的。服務器

      2.服務測試微信

      對於包含多個服務的系統,一個服務測試只測試其中一個單獨服務的功能。只測試一個單獨的服務能夠提升測試的隔離性,這樣咱們能夠更快地定位並解決問題,爲了達到這種隔離性,咱們須要給全部的外部合做者打樁,以便只把服務自己保留在測試範圍內。(打樁是指爲被測服務的請求建立一些有預調響應的服務。)網絡

      640?wx_fmt=png

       對於每一位下游合做者,咱們都須要一個打樁服務,而後在運行服務測試的時候啓動它們,在測試過程當中鏈接這些打樁服務,爲了模仿真實的服務,咱們還須要配置打樁服務返回請求響應。例如,咱們能夠配置積分帳戶爲不一樣的客戶返回不一樣的預設積分。架構

      另外一種替換打樁有方式是mock。與打樁相比,mock還會進一步驗證請求自己是否被正確調用,若是與指望請求不匹配,測試便會失敗,過分使用mock會讓測試變得脆弱。二者之間須要一些權衡。併發

      咱們可使用一些打樁的軟件來協助咱們測試,如Mountebank等。函數

      3.UI測試(端到端測試)

      對於包含多個微服務的系統來講,「端到端的測試」這個名稱相比「UI測試」可能更適合,端到端測試會覆蓋整個系統,這類測試一般用圖形界面來模仿用戶交互動做。這類的測試會覆蓋大範圍的產品代碼,所以當它們經過時你會感受很好。

      640?wx_fmt=png

      由於端到端測試涉及到多個微服務,咱們能夠用扇入模型來解決多個微服務同時開發,同時測試的問題。

      640?wx_fmt=png

      雖然扇入模型能夠來解決一些難題,可是端到端測試仍然有着不少的缺點。

      首先,端到端測試很是脆弱。

      有時測試失敗並非由於功能真的被破壞了,而是由其餘一些緣由引發的,好比其餘服務中止或者網絡故障等,這些跟測試的功能自己沒有關係。

      包含在測試中的服務數量越多,測試就會越脆弱,不肯定性也就越強。

      一個包括脆弱測試的測試套件每每成爲Diane Vaughn所說的異常正常化的受害者,也就是說,隨着時間的推移,咱們對事情出錯變得習覺得常,並開始接受它們是正常的。

      Martin Flower在http://martinflower.com/articles/nonDeterminism.html中提議,在碰到脆弱的測試時應該馬上記錄下來,當不能當即修復時,須要把它們從測試套件中移除,而後就能夠不受打擾地安心修復他們。修復時,看可否經過重寫來避免被測代碼運行在多個線程中,再看是否能讓運行的環境更穩定,更好的辦法是,看可否用不易出問題的小範圍測試取代脆弱的端到端測試。

      單個微服務的測試能夠由這個特性團隊來維護。那麼涉及到多個微服務的端到端測試該由誰負責?

      雖然這種責任分配方式還在探索當中,但將測試對全部人開放或者把這些測試交給專門的團隊來維護都是錯誤的,前者可能會致使團隊成員能夠在無須對測試套件質量有任何理解的狀況下隨意添加測試,這會致使測試用例爆炸,有時致使測試沒有真正的擁有者,當測試失敗時,每一個人都認爲這是別人的問題,而不在意測試是否經過;後者則會致使開發人員沒有在第一時間獲得本身代碼的測試反饋,這會出現很大問題。一個可能的解決方案是,讓各特性團隊共享端到端測試套件的代碼權,對測試套件聯合負責。

      端到端的測試一般須要的時間最長,若是常常有與功能破壞無關的測試失敗,這就是個災難,這樣即便真的是功能被破壞了,也須要花不少長時間才能發現,而此時你們已經轉而作其餘的事情了,切換大腦的上下文來修復測試是很痛苦的。

       咱們能夠用Selenium Grid工具經過並行運行測試來改善緩慢的問題,可是長期的積累,測試用例愈來愈多,但咱們卻不敢刪除測試,而這多是端到端測試面臨着管理、維護困難的局面。咱們應該改變咱們的端到端測試思路,把測試整個系統的重心放到少許核心的場景上來,把任何在這個核心場景以外的功能放到相互隔離的服務測試中覆蓋。

      同時,人們容易有這樣的想法:既然全部服務在這些版本下可以一塊兒工做,爲何不一塊兒部署它們呢?若是接受了這個觀念,慢慢的這成了常態,咱們就會丟棄微服務的主要優點之一,獨立於其餘服務單獨部署一個服務的能力。不用很長時間,原本分享地很好的服務就會與其餘服務糾纏得愈來愈緊密,最終系統雜亂無序,你必須同時部署多個服務。這很是糟糕。

      4.三種測試之間的權衡

      越靠近金字塔的頂端,測試覆蓋的範圍越大,同時咱們對被測後的功能也越有信心,缺點則是須要更長的時間運行測試,反饋週期也會變長,測試失敗後很難定位哪一個功能被破壞;而靠近金字塔的底部,測試更快,反饋週期也會變短,測試失敗後更容易定位破壞的功能和代碼,CI也很短。通常來講,順着金字塔向下,下一層的測試數量要比上一層多一個數量級。

 

三.消費者驅動測試

      使用以前的端到端測試,咱們試圖解決的關鍵問題是什麼?是試圖確保部署新的服務到生產環境後,變動不會破壞新服務的消費。有一種不須要用真正的消費者也能達到相同的目的,咱們可使用消費者驅動的契約(CDC)。當使用CDC時,咱們會定義服務的消費者的指望,這些指望最終會變成對生產者運行的測試代碼,若是使用獲得,CDC應該成爲服務提供者CI的一部分,這樣能夠確保若是這些契約被破壞了,服務提供者沒法部署。

      讓咱們回頭看一下前面圖片中的例子,客戶服務有兩個獨立的消費者:幫助臺和Web客戶端,咱們將建立兩個測試集合(其實就是模擬消費者),每一個集合分別體現幫助臺和Web客戶端對客戶服務的使用方式。由於這些CDC是對客戶服務如何工做的指望,因此,客戶服務自己的全部下游依賴均可以使用打樁,從測試範圍來看,它與測試金字塔中的服務測試位於同一層,但側重點不一樣,這些測試重在消費者如何使用服務。

      Pack(https://github.com/realestate-com-au/pact )是一個消費者驅動的測試工具,開始時,消費者使用Ruby DSL來定義生產者的指望,而後啓動本地一個mock服務器(之後就能夠單獨地來測試消費者),並對其運行這些指望來生成pact規範文件,pack規範文件是一個標準的JSON規範;在生產者這邊,你可使用 JSON Pact規範來驅動對生產者API的調用,而後驗證響應以測試消費者的規範是否被知足,由於生產者代碼須要訪問Pact文件,因此咱們這裏採用JSON。

      Pack的JSON規範是由消費者生成的,該規範須要成爲一個生產者可訪問的構建物,你能夠把它存儲在CI/CD倉庫或Pack Broker中。

      另外Pacto(https://github.com/thoughtworks/pacto )和janus(https://github.com/gga/janus )也是開源的消費契約測試工具。

 

四.線上測試

      在生產環境咱們也須要進行測試,咱們能夠在高峯或請求來臨以前進行測試,這樣能夠發現特定環境中的問題。

      1.冒煙測試

      咱們能夠對生產環境進行冒煙測試,用來幫助咱們識別與環境有關的任何問題,咱們應該把冒煙測試加入到咱們的部署腳本中。

      2.藍綠髮布

      使用藍綠髮布時,咱們會部署兩份軟件,但只有一個接受真正的請求。咱們對新部署的版本運行一些測試,等測試沒有問題時,咱們再切換生產負荷到新部署的版本,一般狀況下,咱們會保留舊版本一小段時間,這樣若是發生任何錯誤,可以快速恢復到舊的版本。這樣能夠下降風險,還能夠大幅減小發布軟件所須要的停機時間,咱們甚至能夠達到零宕機部署。

      3.金絲雀發佈

      金絲雀發佈是指經過將部分流量引流到新部署的系統,來驗證系統是否按預期執行,與藍綠髮布不一樣,金絲雀發佈過程當中,新舊版本共存的時間更長,並且常常會調整流量。

      當考慮使用金絲雀發佈時,你須要選擇是引導部分生產流量到金絲雀,仍是直接複製一份生產請求,若是你選擇複製一份生產請求,而後引導師複製的請求至金絲雀,這樣現行的版本和金絲雀版本將面對相同的請求,只是生產環境的請求是外部可見的,這樣方便你們對新舊版本作比較,同時又避免金絲雀發佈失敗時影響客戶的請求,但複製請求的工做可能會很複雜,尤爲是在請求不冪等的狀況下。

      4.灰度發佈

      灰度發佈是指在黑與白之間,可以平滑過渡的一種發佈方式。AB test就是一種灰度發佈方式,讓一部分用戶繼續用A,一部分用戶開始用B,若是用戶對B沒有什麼反對意見,那麼逐步擴大範圍,把全部用戶都遷移到B上面來。灰度發佈能夠保證總體系統的穩定,在初始灰度的時候就能夠發現、調整問題,以保證其影響度。

      這些部署技術的原則,無外乎說明:更快的從錯誤中修復比想方設法地防範錯誤更重要,固然這不是說防範錯誤不重要,而是由於錯誤不可避免。

 

五.非功能測試

      非功能測試包括一些服務延遲測試、併發量測試、負載量測試、安全性測試、性能測試等。微服務拆分以後,會致使一個功能引起多個微服務的協同工做,這樣跨網絡邊界調用的次數明顯增長了,所以性能測試也是一件很是重要的事。

 

參考

      《微服務設計》(Sam Newman 著 / 崔力強 張駿 譯)

相關文章: 

原文地址:http://www.cnblogs.com/gudi/p/6683305.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

640?wx_fmt=jpeg