從零開始掌握微服務(wù)軟件測(cè)試_第1頁(yè)
從零開始掌握微服務(wù)軟件測(cè)試_第2頁(yè)
從零開始掌握微服務(wù)軟件測(cè)試_第3頁(yè)
從零開始掌握微服務(wù)軟件測(cè)試_第4頁(yè)
從零開始掌握微服務(wù)軟件測(cè)試_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、從零開始掌握微服務(wù)軟件測(cè)試什么是微服務(wù)?微服務(wù)的由來微服務(wù)的前身是Peter Rodgers博士在2005年度云端運(yùn)算博覽會(huì)上提出的微 Web月艮務(wù)(Micro-Web-Service)。微軟的Juval L?wy隨后也提出了類似的想法,并 提議將其作為微軟下一階段最主要的軟件架構(gòu)。2014年,Martin Fowler與James Lewis共同提出了微服務(wù)的概念,給出了微服務(wù) 的具體定義:從本質(zhì)上來說,微服務(wù)是一種架構(gòu)模式。它是面向服務(wù)型架構(gòu)(SOA)的一 種變體,提倡將單一應(yīng)用程序劃分成一組小的服務(wù),服務(wù)之間互相協(xié)調(diào)、互相配合,為用 戶提供最終價(jià)值。每個(gè)服務(wù)運(yùn)行在其獨(dú)立的進(jìn)程中,服務(wù)與服

2、務(wù)之間采用輕量級(jí)的通信機(jī) 制互相溝通(通常是基于HTTP的RESTful API)。每個(gè)服務(wù)都圍繞著具體業(yè)務(wù)進(jìn)行構(gòu) 建,并且能夠被獨(dú)立地部署到生產(chǎn)環(huán)境、類生產(chǎn)環(huán)境等。另外,應(yīng)盡量避免統(tǒng)一的、集中 式的服務(wù)管理機(jī)制,對(duì)具體的一個(gè)服務(wù)而言,應(yīng)根據(jù)業(yè)務(wù)上下文,選擇合適的語(yǔ)言、工具 對(duì)其進(jìn)行構(gòu)建。Martin Fowler是國(guó)際著名的軟件專家,敏捷開發(fā)方法的創(chuàng)始人之一,現(xiàn)為 ThoughtWorks公司的首席科學(xué)家。在面向?qū)ο蠓治鲈O(shè)計(jì)、UML、模式、軟件開發(fā)方法 學(xué)、XP、重構(gòu)等方面,都扮演著舉足輕重的開創(chuàng)者角色。早在20世紀(jì)80年代,F(xiàn)owler 就是使用對(duì)象技術(shù)構(gòu)建多層企業(yè)應(yīng)用的倡導(dǎo)者,他著有幾本

3、經(jīng)典書籍:企業(yè)應(yīng)用架構(gòu)模 式、UML精粹和重構(gòu)等。微服務(wù)與傳統(tǒng)開發(fā)方式的區(qū)別與微服務(wù)架構(gòu)相對(duì)應(yīng),傳統(tǒng)開發(fā)方式通常被稱為單體式架構(gòu)(Monolithic Architecture)。所有功能都打包在一起,基本沒有外部依賴,其中包含了數(shù)據(jù)輸入輸出、數(shù)據(jù)處理、業(yè)務(wù)實(shí)現(xiàn)、錯(cuò)誤處理、前端顯示等所有邏輯。卜圖顯示的一個(gè)典型的單體式架構(gòu)示意圖:這種架構(gòu)有其優(yōu)點(diǎn),包括:開發(fā)團(tuán)隊(duì)的組織架構(gòu)簡(jiǎn)單,便于集中式管理。因?yàn)殚_發(fā)進(jìn)度統(tǒng)一管理,避免重復(fù)開發(fā)的問題。所有功能都集中在本地,不存在分布式的管理和調(diào)用損耗。但是,隨著現(xiàn)代應(yīng)用程序的日益復(fù)雜化,加上對(duì)于迭代速度的要求越來越高,這種架 構(gòu)的不足開始暴露出來:效率低:所有

4、開發(fā)人員都在同一個(gè)項(xiàng)目下修改代碼,經(jīng)常需要相互等待對(duì)方的功能更 新,代碼入庫(kù)時(shí)的沖突不斷,造成極高的開發(fā)成本。維護(hù)難:各個(gè)模塊的代碼都耦合在一起,一方面新人不知道從何下手,一方面一旦出 現(xiàn)問題(Bug),就需要大改。在某個(gè)模塊需要升級(jí)時(shí),也不得不升級(jí)整個(gè)應(yīng)用程序。不靈活:構(gòu)建(Build)時(shí)間過長(zhǎng),任何一個(gè)小量級(jí)的修改,都要重構(gòu)整個(gè)項(xiàng)目,非常 耗時(shí)。穩(wěn)定性差:一個(gè)微小的問題,都可能導(dǎo)致整個(gè)進(jìn)程崩潰,使得整個(gè)應(yīng)用程序無(wú)法工 作。擴(kuò)展性不夠:難以分布式部署和擴(kuò)容,無(wú)法滿足高并發(fā)下的業(yè)務(wù)需求。而且,一旦業(yè) 務(wù)范圍擴(kuò)展或者需求有所變化,難以復(fù)用原有的服務(wù),必須重新開發(fā)。如何解決這些問題?微服務(wù)架構(gòu)逐漸

5、浮出水面。從軟件開發(fā)的組織上來說,它的核心 理念是按照業(yè)務(wù)邊界把整個(gè)系統(tǒng)劃分為若干個(gè)子系統(tǒng)。每個(gè)子系統(tǒng)的開發(fā)團(tuán)隊(duì)之間, 保持著合作(Inter-Operate)而不是整合(Intergrate)的關(guān)系。定義好每個(gè)子系統(tǒng)的邊 界和接口,在一個(gè)團(tuán)隊(duì)內(nèi)自治。團(tuán)隊(duì)按照這樣的方式組建,溝通的成本維持在系統(tǒng)內(nèi)部, 每個(gè)子系統(tǒng)就會(huì)更加內(nèi)聚,彼此的依賴耦合能變?nèi)?,跨系統(tǒng)的溝通成本也就能降低。這里不得不提及著名的康威定律”(Conways Law),這是微服務(wù)架構(gòu)的一個(gè)核 心理念。Melvin Conway 在 1967 年提出了這個(gè)理念,原文是:Organizations which design syste

6、ms are constrained to produce designs which are copies of the communication structures of these organizations.用簡(jiǎn)單的話來說,就是組織形式等同于系統(tǒng)設(shè)計(jì),組織的溝通方式會(huì)通過系統(tǒng)設(shè)計(jì)表 現(xiàn)出來。下面這幅著名的軟件企業(yè)組織圖,與這些企業(yè)的產(chǎn)品架構(gòu)有著異曲同工的對(duì)應(yīng)關(guān) 系。再以上面提到的單體式App為例,通過用微服務(wù)架構(gòu)方式對(duì)其進(jìn)行改造,將會(huì)變成 下面這種結(jié)構(gòu):除了解決單體式架構(gòu)的幾個(gè)缺陷以外,微服務(wù)架構(gòu)還具有下面這些優(yōu)點(diǎn):部署、回滾變得更快、更簡(jiǎn)便。微服務(wù)架構(gòu)中,提倡針對(duì)不同的業(yè)務(wù)特征選

7、擇合適的技術(shù)方案,有針對(duì)性的解決具體 業(yè)務(wù)問題,而不是像單塊架構(gòu)中采用統(tǒng)一的平臺(tái)或技術(shù)來解決所有問題。這樣就實(shí)現(xiàn)了技 術(shù)的多元化,無(wú)需長(zhǎng)時(shí)間鎖定于某一種技術(shù)棧,便于采用最新的工具。每個(gè)服務(wù)都可以單獨(dú)擴(kuò)容。在需要發(fā)布新功能時(shí),可以用插件的形式添加到系統(tǒng)中而不需要重新部署整個(gè)系統(tǒng)。微服務(wù)架構(gòu)提供自主管理其相關(guān)的業(yè)務(wù)數(shù)據(jù),這樣可以隨著業(yè)務(wù)的發(fā)展提供數(shù)據(jù)接口 集成,而不是以數(shù)據(jù)庫(kù)的方式同其他服務(wù)集成。另外,隨著業(yè)務(wù)的發(fā)展,可以方便地選擇 更合適的工具管理或者遷移業(yè)務(wù)數(shù)據(jù)。當(dāng)然也需要提到,微服務(wù)架構(gòu)也存在著它的不足:由于把每個(gè)子系統(tǒng)分配各不同的團(tuán)隊(duì),這不僅意味著系統(tǒng)內(nèi)部通信需求的增加,也帶 來了不同團(tuán)隊(duì)

8、之間交流成本的提高。在對(duì)基于微服務(wù)架構(gòu)的分布式系統(tǒng)進(jìn)行測(cè)試時(shí),復(fù)雜度會(huì)大幅度提高。分布式部署會(huì)給團(tuán)隊(duì)的DevOps能力提出更高的要求。當(dāng)服務(wù)數(shù)量增加時(shí),管理的復(fù)雜度也會(huì)指數(shù)級(jí)增加。DevOps( Development和Operations的組合詞)是一種重視軟件開發(fā)人員和IT 運(yùn)維技術(shù)人員之間溝通合作的文化、流程或者實(shí)踐方式。透過完全自動(dòng)的軟件交付”和 架構(gòu)變更流程,使得構(gòu)建、測(cè)試、發(fā)布軟件更加快捷、頻繁和可靠。微服務(wù)架構(gòu)對(duì)測(cè)試人員意味著什么?介紹完微服務(wù)架構(gòu)以后,回到主題上來:對(duì)于測(cè)試人員而言,微服務(wù)架構(gòu)到底有什么 特點(diǎn)呢?我把它歸結(jié)為以下幾點(diǎn):每個(gè)服務(wù)承擔(dān)一定的職責(zé):盡可能小,但是又達(dá)到

9、必要的規(guī)模(as small as possible but as big as necessary)。在問答網(wǎng)站Quora上,有一個(gè)著名的問題:什么是程序員覺得最浪費(fèi)時(shí)間的事情? 排名第一的回答中提到:不必要的微服務(wù)。這句話揭示了開發(fā)團(tuán)隊(duì)在轉(zhuǎn)向微服務(wù)架構(gòu)時(shí)經(jīng)常走入的誤區(qū)。微固然重要,但是 首要的是提供服務(wù),這才構(gòu)成微服務(wù)的價(jià)值。盲目地切分功能(Feature),卻 沒有起到解耦合的作用,只是會(huì)增加維護(hù)、測(cè)試的成本。畢竟,多一項(xiàng)服務(wù),就會(huì)多出一 系列的流水線和測(cè)試要求。因此,測(cè)試、質(zhì)量人員在面臨團(tuán)隊(duì)計(jì)劃采取微服務(wù)架構(gòu)的決策 時(shí),必須要敢于質(zhì)疑:是否有這樣做的必要?目的是讓決策人員意識(shí)到這種轉(zhuǎn)型

10、的潛在成 本,避免花無(wú)用功。微服務(wù)之間通常通過Rest over HTTP連接。最常見的連接/交互方式,即通過POST、GET、PUT、DELETE這些命令操作API, 通過JSON傳遞參數(shù)。以下面這個(gè)典型的制造型企業(yè)的運(yùn)營(yíng)系統(tǒng)為例。在從單體式架構(gòu) 轉(zhuǎn)為微服務(wù)之后,不同功能模塊之間將通過Rest方式互相訪問。這種簡(jiǎn)易、明確的交互方式為契約測(cè)試(Contract Test)提供了基礎(chǔ)。每種服務(wù)不一定提供用戶界面。這意味著每種服務(wù)的測(cè)試,并不一定能夠或者需要從UI完成。這對(duì)API級(jí)別的集 成化測(cè)試提出了要求。微服務(wù)通常還可以劃分為更小的模塊。如下圖所示,一個(gè)典型的微服務(wù)可以分為這幾個(gè)模塊:資源、業(yè)

11、務(wù)邏輯、數(shù)據(jù)存儲(chǔ)接 口、外部通信接口等。這意味著,在對(duì)微服務(wù)架構(gòu)進(jìn)行測(cè)試時(shí),可以從不同的模塊著手,進(jìn)行相應(yīng)的模塊測(cè) 試??偨Y(jié)簡(jiǎn)單總結(jié)一下所學(xué)習(xí)的內(nèi)容:微服務(wù)架構(gòu)是針對(duì)單體式架構(gòu)的不足,隨著應(yīng)用程序復(fù)雜度的增加、部署頻率加快的 要求,應(yīng)運(yùn)而生。微服務(wù)架構(gòu)帶來了簡(jiǎn)化部署、隔離功能/缺陷、便于升級(jí)/擴(kuò)容等優(yōu)點(diǎn),但也具有提高 交流成本、增加測(cè)試復(fù)雜度等不足。對(duì)于測(cè)試人員,微服務(wù)架構(gòu)具備一些特別需要注意的特征,要求采用不同的測(cè)試方法 加以應(yīng)對(duì)。微服務(wù)對(duì)軟件測(cè)試提出的挑戰(zhàn)在上一節(jié)里,我們學(xué)習(xí)了微服務(wù)的來源和主要特點(diǎn)。對(duì)于軟件測(cè)試人員而言,微服務(wù) 架構(gòu)對(duì)軟件測(cè)試帶來了哪些新的挑戰(zhàn)呢?我們應(yīng)該用什么樣的策略和

12、方法來迎接這些挑 戰(zhàn)?總體的測(cè)試策略軟件測(cè)試的目的是確保軟件產(chǎn)品的質(zhì)量符合預(yù)期。衡量測(cè)試質(zhì)量的指標(biāo)有很多,最常 見的是測(cè)試覆蓋率和測(cè)試成本(包括測(cè)試所用時(shí)間、測(cè)試維護(hù)成本),而衡量測(cè)試效果的 主要手段則是最終產(chǎn)品在實(shí)際使用中暴露出來的問題數(shù)量(Bug Number)。具體到采用微服務(wù)架構(gòu)的產(chǎn)品而言,Martin Fowler在關(guān)于軟件測(cè)試的論述中提出了其目的:開發(fā)團(tuán)隊(duì)采用的任何測(cè)試策略,都應(yīng)當(dāng)力求為服務(wù)內(nèi)部每個(gè)模塊的完整性,以及每個(gè) 模塊之間、各個(gè)服務(wù)之間的交互,提供全面的測(cè)試覆蓋率,同時(shí)還要保持測(cè)試的輕便快 捷。因此,我們需要采取下面幾點(diǎn)測(cè)試策略:我們一方面要保證從各個(gè)維度上,無(wú)一遺漏地對(duì)微

13、服務(wù)進(jìn)行全面的測(cè)試,特別是對(duì)于 分布式的系統(tǒng),系統(tǒng)的所有層次都必須被覆蓋到;另一方面又要確保測(cè)試執(zhí)行的快捷,這 樣才能保證持續(xù)集成/持續(xù)交付(CI/CD)的實(shí)現(xiàn)。要確保測(cè)試策略的正確實(shí)施,工具和技術(shù)固然重要,然而,首先需要測(cè)試人員在團(tuán)隊(duì) 中樹立起提倡質(zhì)量第一的測(cè)試文化:無(wú)法通過測(cè)試的代碼不應(yīng)該被合并到代碼倉(cāng)庫(kù)里;無(wú)法通過測(cè)試的代碼不應(yīng)該被發(fā)布出去。不能為了測(cè)試而測(cè)試,測(cè)試的真正目的是為了交付高質(zhì)量的軟件給用戶,而不是把資 源浪費(fèi)在沒有實(shí)際意義的測(cè)試用例上。所有的測(cè)試層次、流程和用例,都應(yīng)該有的放矢。傳統(tǒng)測(cè)試方法面臨的挑戰(zhàn)以一個(gè)常見的開發(fā)團(tuán)隊(duì)為例,在采用了微服務(wù)架構(gòu)之后,很可能同時(shí)會(huì)開發(fā)多個(gè)模塊

14、 (即微服務(wù)),每個(gè)微服務(wù)有不同的客戶要求、開發(fā)周期、開發(fā)進(jìn)度和交付期限,但是整 個(gè)團(tuán)隊(duì)又必須保證能夠在固定的時(shí)間節(jié)點(diǎn)(譬如每月一次、每?jī)芍芤淮?,甚至每天一次?者多次),持續(xù)地、穩(wěn)定地為用戶提供可以部署、使用的產(chǎn)品。這意味著,過去那種先等 產(chǎn)品經(jīng)理、業(yè)務(wù)部門提供需求,開發(fā)人員再進(jìn)行開發(fā),最后交給測(cè)試人員執(zhí)行集成測(cè)試、 端到端測(cè)試的方法,已經(jīng)無(wú)法提供足夠的測(cè)試粒度和足夠快的響應(yīng)速度。歸結(jié)起來,與基于單體式架構(gòu)的傳統(tǒng)測(cè)試方法相比,微服務(wù)架構(gòu)對(duì)測(cè)試提出了以下挑 戰(zhàn):服務(wù)/模塊/層次(layer)之間存在復(fù)雜的依賴性。在單體式架構(gòu)中,通常使用集成測(cè)試來驗(yàn)證依賴是否正常。而在微服務(wù)架構(gòu)中,服務(wù) 數(shù)量往

15、往很多,每個(gè)服務(wù)都是獨(dú)立的業(yè)務(wù)單元,服務(wù)之間主要通過接口進(jìn)行交互,如何保 證這些依賴的正常,是測(cè)試人員面臨的主要挑戰(zhàn)。這意味著,如果想單獨(dú)測(cè)試某一個(gè)服 務(wù),或者服務(wù)中的某個(gè)模塊,就必須剝離它們對(duì)于其他環(huán)節(jié)的依賴關(guān)系。這需要通過 Mock、Stub等方法來實(shí)現(xiàn)。不同的服務(wù)可能會(huì)在不同的環(huán)境/設(shè)置下運(yùn)行。特別是一些后端服務(wù),與前端服務(wù)的運(yùn)行環(huán)境可能截然不同。這時(shí)在考慮對(duì)每種服務(wù) 設(shè)立自動(dòng)化管線時(shí),就必須有針對(duì)性的設(shè)置相應(yīng)的環(huán)境配置。而且,在微服務(wù)架構(gòu)中,每 個(gè)服務(wù)都獨(dú)立部署,交付周期短且頻率高,人工部署已經(jīng)無(wú)法適應(yīng)業(yè)務(wù)的快速變化。因此 如何有效地構(gòu)建自動(dòng)化部署體系,保證配置的穩(wěn)定性、可重復(fù)性,是微

16、服務(wù)測(cè)試面臨的另 一個(gè)挑戰(zhàn),必須與DevOps人員一同解決。涉及多個(gè)服務(wù)的UI端到端測(cè)試(End-to-End測(cè)試,簡(jiǎn)稱E2E測(cè)試)非常容易出 錯(cuò)。因?yàn)槊糠N服務(wù)的開發(fā)進(jìn)度不同,集成不同服務(wù)的端到端測(cè)試往往會(huì)因?yàn)槟骋粋€(gè)服務(wù)的 微小改動(dòng)而出錯(cuò)。這種出錯(cuò)是測(cè)試人員希望避免的干擾信息。這意味著,對(duì)端到端測(cè)試的 設(shè)計(jì),必須采取一定的防干擾、防誤報(bào)策略。測(cè)試結(jié)果可能取決于網(wǎng)絡(luò)的穩(wěn)定性。微服務(wù)架構(gòu)是基于分布式的系統(tǒng),而構(gòu)建分布式系統(tǒng)必然會(huì)帶來額外的開銷。性能:分布式系統(tǒng)是跨進(jìn)程、跨網(wǎng)絡(luò)的調(diào)用,受網(wǎng)絡(luò)延遲和帶寬的影響??煽啃裕河捎诟叨纫蕾囉诰W(wǎng)絡(luò)狀況,任何一次的遠(yuǎn)程調(diào)用都有可能失敗,隨著服務(wù)的 增多還會(huì)出現(xiàn)更多

17、的潛在故障點(diǎn)。因此,如何提高系統(tǒng)的可靠性、降低因網(wǎng)絡(luò)引起的故障 率,是系統(tǒng)構(gòu)建的一大挑戰(zhàn)。異步:異步通信大大增加了功能實(shí)現(xiàn)的復(fù)雜度,并且伴隨著定位難、調(diào)試難等問題。數(shù)據(jù)一致性:要保證分布式系統(tǒng)的數(shù)據(jù)強(qiáng)一致性,成本是非常高的,需要在C(- 致性)A (可用性)P (分區(qū)容錯(cuò)性)三者之間做出權(quán)衡。特別是涉及到數(shù)據(jù)存儲(chǔ)和外部通信的部分,如果在測(cè)試中不擺脫這些因素的影響,就 可能會(huì)得到一些隨機(jī)性的誤報(bào),干擾測(cè)試結(jié)果。故障分析的復(fù)雜度會(huì)隨著服務(wù)的增加而提高。微服務(wù)架構(gòu)中,因?yàn)槊總€(gè)服務(wù)都需要獨(dú)立地配置、部署、監(jiān)控和收集日志,因此在發(fā) 現(xiàn)問題之后,進(jìn)行診斷分析時(shí),搜集缺陷信息的成本呈指數(shù)級(jí)增長(zhǎng)。與交付周期不

18、同的開發(fā)團(tuán)隊(duì)之間的交流成本。這一點(diǎn)雖然跟技術(shù)無(wú)關(guān),但是實(shí)際上會(huì)對(duì)測(cè)試人員的工作造成很大的困擾。因?yàn)殚_發(fā) 模式分解為負(fù)責(zé)不同服務(wù)的多個(gè)小組,測(cè)試人員往往每天要花費(fèi)大量的時(shí)間,了解不同團(tuán) 隊(duì)的開發(fā)進(jìn)度。如果還需要手動(dòng)進(jìn)行回歸測(cè)試(Regression Test),最終將會(huì)不堪重負(fù)。 所以自動(dòng)化測(cè)試是必須采取的手段和方向。如何應(yīng)對(duì)這些挑戰(zhàn),我總結(jié)了下面這三個(gè)原則:自動(dòng)化:測(cè)試任務(wù)的增加,要求測(cè)試人員必須把主要的精力用于將測(cè)試自動(dòng)化,擺 脫手動(dòng)測(cè)試帶來的沉重負(fù)擔(dān)。當(dāng)然,自動(dòng)化測(cè)試必須足夠穩(wěn)定、穩(wěn)健,不能動(dòng)輒誤報(bào),否 則反而會(huì)導(dǎo)致很高的維護(hù)成本。層次化:這意味著采用分層次的測(cè)試方法,粒度由細(xì)到粗,范圍由

19、小到大。這就是Mike Cohn提出的測(cè)試金字塔(Test Pyramid ),其中最重要的兩個(gè)原則 是:應(yīng)該用不同的粒度來測(cè)試應(yīng)用程序;層次越高,測(cè)試越少。最底層的是單元測(cè)試(Unit Test),粒度最細(xì),速度最快,維護(hù)成本也最低。往上是 針對(duì)每種服務(wù)內(nèi)部的各種模塊、業(yè)務(wù)流程的測(cè)試。最上面是基于前端UI的測(cè)試,這部分 的粒度最粗,范圍最大(因?yàn)闀?huì)覆蓋大多數(shù)服務(wù)),但是維護(hù)成本最高,因?yàn)樯晕⒂行┘?xì) 微的變化就可能需要調(diào)整腳本。而且,由于基于前端,需要設(shè)置很多響應(yīng)時(shí)間和等待時(shí) 間,所以速度最慢。Mike Cohn是Scrum軟件開發(fā)方法的提出者之一,也是Scrum聯(lián)盟的創(chuàng)始成 員。他目前是Mo

20、untain Goat Software公司的所有者,致力于提供關(guān)于Scrum和 Agile軟件開發(fā)技術(shù)的培訓(xùn)??梢暬簽榱私档徒涣鞒杀?,最好的辦法就是讓所有的測(cè)試結(jié)果可視化。這意味著 將構(gòu)建(Build)、測(cè)試(Test)、部署(Deploy)所有這些相關(guān)任務(wù)構(gòu)建在一個(gè)流水線 之中,讓所有團(tuán)隊(duì)成員都可以隨時(shí)監(jiān)控項(xiàng)目進(jìn)度,找到阻礙項(xiàng)目的瓶頸。以下面這個(gè)典型團(tuán)隊(duì)為例,整個(gè)從開發(fā)、測(cè)試、構(gòu)建到部署的一系列過程,都可以借 助Jenkins或者TeamCity這樣的任務(wù)調(diào)度工具,完全可視化,再借助SonarQube這 樣的代碼質(zhì)量監(jiān)控工具監(jiān)控測(cè)試結(jié)果。Google Analytics或者M(jìn)icroso

21、ft的Azure ApplicationInsight等云端監(jiān)控工具,則可以提供實(shí)時(shí)生產(chǎn)環(huán)境的客戶使用信息或者測(cè)試 數(shù)據(jù),讓整個(gè)團(tuán)隊(duì)可以隨時(shí)把握產(chǎn)品的整個(gè)流水線的運(yùn)行狀態(tài)。在微服務(wù)架構(gòu)中所采用的主要測(cè)試方法。如下圖所示,它們主要包括:End to EndTeslsDeploy In QA EnvironmentIntegration Tests5Code DevelopmentUnit TestsBuild Service單元測(cè)試(Unit Test)用于驗(yàn)證微服務(wù)內(nèi)部的類方法或函數(shù)的行為。它們會(huì)根據(jù)測(cè)試框架,執(zhí)行代碼文件里 的類方法或函數(shù),提供不同的輸入,并驗(yàn)證與每一個(gè)輸入相對(duì)應(yīng)的輸出。集成

22、測(cè)試(Integration Test)用于驗(yàn)證微服務(wù)與外部模塊的通信或者交互行為。測(cè)試框架會(huì)啟動(dòng)服務(wù)的一個(gè)實(shí)例, 并調(diào)用服務(wù)的外部接口來執(zhí)行業(yè)務(wù)邏輯。組件測(cè)試(Component Test)即驗(yàn)證微服務(wù)能否起到預(yù)期的作用。這需要把微服務(wù)周邊依賴的所有其他服務(wù)或者資 源全部模擬化,從該服務(wù)外部用戶的角度來檢查服務(wù)能否提供預(yù)期的輸出。端到端測(cè)試(End-to-end Test)驗(yàn)證整個(gè)系統(tǒng)的功能能否符合用戶的預(yù)期,一般是從UI層面進(jìn)行測(cè)試,確保用戶體 驗(yàn)完全達(dá)到客戶要求。探索測(cè)試(Exploratory Test,即手動(dòng)測(cè)試)這一步通常由業(yè)務(wù)專家型用戶執(zhí)行,具體查看某個(gè)新添加的特性是否開發(fā)、部署

23、成 功??偨Y(jié)簡(jiǎn)單總結(jié)一下所學(xué)習(xí)的內(nèi)容:微服務(wù)架構(gòu)對(duì)軟件測(cè)試提出了很多全新的挑戰(zhàn)。應(yīng)對(duì)這些挑戰(zhàn)的方法包括:自動(dòng)化層次化可視化怎么針對(duì)微服務(wù)架構(gòu)做單元測(cè)試?單元測(cè)試是開發(fā)人員編寫的一小段代碼,用于檢驗(yàn)被測(cè)代碼的一個(gè)很小的、很明確的 功能是否正確。通常而言,一個(gè)單元測(cè)試是用于判斷某個(gè)特定條件(或者場(chǎng)景)下某個(gè)特 定函數(shù)的行為。例如,你可能把一個(gè)很大的值放入一個(gè)有序list中去,然后確認(rèn)該值出現(xiàn) 在list的尾部。或者,你可能會(huì)從字符串中刪除匹配某種模式的字符,然后確認(rèn)字符串確 實(shí)不再包含這些字符了。對(duì)于單元測(cè)試中單元的含義,一般來說,要根據(jù)實(shí)際情況去判定其具體含義,如C 語(yǔ)言中單元指一個(gè)函數(shù),Jav

24、a里單元指一個(gè)類,前端應(yīng)用中可以指一個(gè)窗口或一個(gè)菜單 等??偟膩碚f,單元就是人為規(guī)定的最小的被測(cè)功能模塊。我們將探討在微服務(wù)架構(gòu)下,單元測(cè)試的設(shè)計(jì)、實(shí)現(xiàn)和質(zhì)量控制。設(shè)計(jì):定義測(cè)試邊界要設(shè)計(jì)高效率(既運(yùn)行快速又覆蓋率高)的單元測(cè)試,首要要準(zhǔn)確地定義測(cè)試邊界。 測(cè)試的目的就是為了驗(yàn)證邊界里黑盒的行為是否符合預(yù)期,我們向黑盒輸入數(shù)據(jù),然 后驗(yàn)證輸出的正確性。在單元測(cè)試?yán)?,黑盒指的是函?shù)或者類的方法,目的是單獨(dú)測(cè)試特 定代碼塊的行為。但是在微服務(wù)架構(gòu)中,很多時(shí)候黑盒的輸出需要依賴于其他的功能或者服務(wù),即存在夕卜部依賴。為了更好地理解這個(gè)概念,我們以一個(gè)簡(jiǎn)單的注冊(cè)功能為例:輸入?yún)?shù);UserEiame-

25、 WangdongPassword 明乂密暗從圖中可以看出,這個(gè)函數(shù)包含了一些輸入和輸出。輸入?yún)?shù)包括基本的用戶注冊(cè)信息(姓名、用戶名和密碼),而返回新創(chuàng)建的用戶ID。但是在此過程中,還有一些不是很明顯的輸入數(shù)據(jù)。這個(gè)函數(shù)調(diào)用了兩個(gè)外部函數(shù): db.user.inser()是向數(shù)據(jù)庫(kù)插入數(shù)據(jù);Password.hashAndsave()是一個(gè)微服務(wù),用于生 成密碼的哈希值,再加以保存。在某些情況下,數(shù)據(jù)庫(kù)可能會(huì)返回錯(cuò)誤,比如用戶名已經(jīng) 存在,導(dǎo)致數(shù)據(jù)庫(kù)插入失敗。另外,因?yàn)樾枰{(diào)用外部的微服務(wù)生成密碼哈希值,如果網(wǎng) 絡(luò)連接出現(xiàn)問題,或者哈希值生成服務(wù)由于發(fā)生過載而導(dǎo)致服務(wù)超時(shí),那么密碼保存就會(huì)

26、返回錯(cuò)誤。User.create()函數(shù)必須能夠妥善地處理這兩種錯(cuò)誤,這是測(cè)試的重點(diǎn)。也就是說,為了全面地測(cè)試用戶注冊(cè)功能,單元測(cè)試所要做的不僅僅是簡(jiǎn)單地輸入各 種不同的參數(shù),它還要能夠讓外部函數(shù)/微服務(wù),能夠產(chǎn)生出指定的錯(cuò)誤,再驗(yàn)證函數(shù)的錯(cuò) 誤處理邏輯是否符合預(yù)期。因此,為了在不依賴于外部條件的情況下制造出各種輸入數(shù)據(jù),就需要使用Stub或 者M(jìn)ock,中文可以理解為對(duì)函數(shù)外部依賴的模擬器。簡(jiǎn)而言之,它意味著用一個(gè)假的版 本替換了真實(shí)的對(duì)象(例如一個(gè)類、模塊、函數(shù)或者微服務(wù))。假的版本的行為特征和真實(shí)對(duì)象非常類似,采用相同的調(diào)用方法,并按照你在測(cè)試開始之前預(yù)定義的返回方式,提 供返回?cái)?shù)據(jù)。測(cè)

27、試框架在運(yùn)行被測(cè)試的函數(shù)時(shí),可以把對(duì)外部依賴函數(shù)服務(wù)的調(diào)用,重定 向到Stub 上,這樣單元測(cè)試就可以在沒有外部服務(wù)的情況下進(jìn)行,即保證了速度,又避 免了網(wǎng)絡(luò)條件的影響。這里再?gòu)?qiáng)調(diào)下Stub和Mock的區(qū)別,很多人經(jīng)常搞混。Stub就是一個(gè)純粹的模 擬器,用于替代真實(shí)的服務(wù)/函數(shù),收到請(qǐng)求返回指定結(jié)果,不會(huì)記錄任何信息。Mock 則更進(jìn)一步,還會(huì)記錄調(diào)用行為,可以根據(jù)行為來驗(yàn)證系統(tǒng)的正確性。創(chuàng)建Stub的工具有很多,包括Node.js/JavaScript框架下的sinon.js, testdouble.js 等;Python 下的 mock 等。在剛剛提到的注冊(cè)函數(shù)和密碼哈希值生成、保存服務(wù)

28、之間我們可以使用模擬器來達(dá)到各種目的:模擬器可返回任意的設(shè)定值,用于模擬外部函數(shù)的輸出。這在測(cè)試罕見的邊界情況時(shí) 會(huì)非常有用,比如有些錯(cuò)誤場(chǎng)景可能很少發(fā)生或者非常難以重現(xiàn)。模擬器也可以捕捉被測(cè)試函數(shù)傳給外部函數(shù)的參數(shù),或者把這些參數(shù)記錄下來。這樣 就可以驗(yàn)證被測(cè)試函數(shù)需要調(diào)用哪些外部函數(shù),以及需要傳給外部函數(shù)哪些參數(shù)。通過對(duì)外部依賴函數(shù)使用模擬器,通??梢栽趲酌腌妰?nèi),執(zhí)行數(shù)千個(gè)單元測(cè)試。這 樣,開發(fā)人員就可以把單元測(cè)試加入到日常的開發(fā)工作管線(Pipeline)當(dāng)中,包括直接 集成到常用的IDE里,或者通過終端命令行觸發(fā)。通過在編寫代碼的同時(shí),頻繁運(yùn)行單 元測(cè)試,有助于盡早發(fā)現(xiàn)代碼中的問題。對(duì)

29、于程序員來說,如果養(yǎng)成了對(duì)自己寫的代碼進(jìn) 行單元測(cè)試的習(xí)慣,不但可以寫出高質(zhì)量的代碼,而且還能提高編程水平。順便說一句,在微服務(wù)架構(gòu)中,單元測(cè)試的作用不僅限于代碼開發(fā),它們還對(duì) DevOps/CI (持續(xù)集成)有很大的幫助,可以集成到代碼合并(Merge)流程里。譬如,GitHub支持對(duì)一些主流CI服務(wù)的狀態(tài)檢查。一般它會(huì)限制對(duì)Master”主 分支的提交權(quán)限,不允許開發(fā)人員直接向該分支提交代碼,而是要求他們把代碼先提交到 其他分支上(提交Pull Request),再由其他開發(fā)人員進(jìn)行代碼審查(CodeReview )。最后,在將代碼合并到主分支的時(shí)候,GitHub要求先通過狀態(tài)檢查。這時(shí),

30、 Jenkins、CircleCI和TravisCI等CI服務(wù)都提供了狀態(tài)檢查鉤子(hook),它們會(huì)從 分支上獲取代碼并運(yùn)行單元測(cè)試。如果通過了,就允許合并代碼,否則就不允許實(shí)現(xiàn):?jiǎn)卧獪y(cè)試的流程單元測(cè)試的工具有很多,例如:C+ : Googletest、GMockJava : Junit、TestNG、Mockito、PowerMockJavaScript: Qunit、JasminePython : unittestLua : luaunit一個(gè)單元測(cè)試的實(shí)現(xiàn)主要分為以下幾步:設(shè)置測(cè)試數(shù)據(jù);在測(cè)試中調(diào)用你的方法;判斷返回的結(jié)果是否符合預(yù)期。這三步可以簡(jiǎn)化為三A原則” :Arrange (設(shè)置)、Act (調(diào)用)、Assert (檢 查)?;蛘咭部梢越栌肂DD (行為驅(qū)動(dòng)測(cè)試)的概念,把單元測(cè)試的流程分為三步:Given (上下文)、When (事件)、Then (結(jié)果)。卜面我們來看一個(gè)真實(shí)的例子,這是一個(gè)名為Examplecontroller的類,用于在人 名庫(kù)(PersonRepository)中查找人名。下面,我們將用Junit,對(duì)類中的hello( lastn

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論