成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

十年架構(gòu)師耗盡心血帶你如何進(jìn)行微服務(wù)的單元、集成和系統(tǒng)測(cè)試?

開發(fā) 架構(gòu) 測(cè)試
對(duì)于測(cè)試工作而言,微服務(wù)架構(gòu)對(duì)于傳統(tǒng)的架構(gòu)引入了更多的復(fù)雜性。一方面,隨著微服務(wù)數(shù)量的增長(zhǎng),測(cè)試的用例也會(huì)持續(xù)增長(zhǎng);另一方面,由于微服務(wù)之間存在著一定的依賴性,在測(cè)試過(guò)程中如何來(lái)處理這些依賴,就變得極為重要。

如何進(jìn)行微服務(wù)的測(cè)試

對(duì)于測(cè)試工作而言,微服務(wù)架構(gòu)對(duì)于傳統(tǒng)的架構(gòu)引入了更多的復(fù)雜性。一方面,隨著微服務(wù)數(shù)量的增長(zhǎng),測(cè)試的用例也會(huì)持續(xù)增長(zhǎng);另一方面,由于微服務(wù)之間存在著一定的依賴性,在測(cè)試過(guò)程中如何來(lái)處理這些依賴,就變得極為重要。

本節(jié)將從微服務(wù)架構(gòu)的單元測(cè)試、集成測(cè)試和系統(tǒng)測(cè)試三個(gè)方面來(lái)展開討論。

[[339279]]

 

微服務(wù)的單元測(cè)試

單元測(cè)試要求將測(cè)試范圍局限在服務(wù)內(nèi)部,這樣可以保證測(cè)試的隔離性,將測(cè)試的影響減少到最小。在實(shí)際編碼之前,TDD要求程序員先編寫測(cè)試用例。當(dāng)然,一開始,所有的測(cè)試用例應(yīng)該是全部失敗的,然后再寫代碼讓這些測(cè)試用例逐個(gè)通過(guò)。也就是說(shuō),編寫足夠的測(cè)試用例使測(cè)試失敗,編寫足夠的代碼使測(cè)試成功。這樣,程序員編碼的目的就會(huì)更加明確。

當(dāng)然,編寫測(cè)試用例并非是TDD的全部。在測(cè)試成功之后,還需要對(duì)成功的代碼及時(shí)進(jìn)行重構(gòu),從而消除代碼的“壞味道”。

1.為什么需要重構(gòu)代碼

所謂重構(gòu),簡(jiǎn)而言之,就是在不改變代碼外部行為的前提下,對(duì)代碼進(jìn)行修改,以改善程序的內(nèi)部結(jié)構(gòu)。

重構(gòu)的前提是代碼的行為是正確的,也就是說(shuō),關(guān)于代碼功能已經(jīng)經(jīng)過(guò)測(cè)試,并且測(cè)試通過(guò)了,這是重構(gòu)的前提。只有正確的代碼才有重構(gòu)意義。

那么,既然代碼都正確了,為什么還要花費(fèi)時(shí)間再去改動(dòng)代碼、重構(gòu)代碼呢?

重構(gòu)的原因是大部分程序員無(wú)法寫出完美的代碼。他們無(wú)法對(duì)自己編寫的代碼完全信任,這也是需要對(duì)自己所寫的代碼進(jìn)行測(cè)試的原因,重構(gòu)也是如此。歸納起來(lái),以下幾方面是軟件需要重構(gòu)的原因。

  • ·軟件不一定一開始就是正確的。天才程序員只是少數(shù),大多數(shù)人不可避免會(huì)犯錯(cuò),所以很多程序員無(wú)法一次性寫出正確的代碼,只能不斷地測(cè)試、不斷地重構(gòu),以改善代碼。連MartinFowler這樣的大師都承認(rèn)自己的編碼水平也同大多數(shù)人一樣,是需要測(cè)試及重構(gòu)的。
  • ·隨著時(shí)間推移,軟件的行為變得難以理解。這種現(xiàn)象特別集中在一些規(guī)模大、歷史久、代碼質(zhì)量差的軟件里面。這些軟件的實(shí)現(xiàn),或者脫離了最初的設(shè)計(jì),或者混亂不堪,讓人無(wú)法理解,特別是缺少“活文檔”來(lái)進(jìn)行指導(dǎo),這些代碼最終會(huì)“腐爛變味”。
  • ·能運(yùn)行的代碼,并不一定是好代碼。任何程序員都能寫出計(jì)算機(jī)能理解的代碼,唯有寫出人類容易理解的代碼,才是優(yōu)秀的程序員。

正是目前軟件行業(yè)這些事實(shí)的存在,促使重構(gòu)成為TDD中必不可少的實(shí)踐之一。程序員對(duì)程序進(jìn)行重構(gòu),是出于以下的目的。

  • 消除重復(fù)。代碼在首次編碼時(shí),單純只是為了讓程序通過(guò)測(cè)試,其間可能會(huì)有大量的重復(fù)代碼,以及“僵尸代碼”的存在,所以需要在重構(gòu)階段消除重復(fù)代碼。
  • 使代碼易理解、易修改。在一開始,程序員優(yōu)先考慮的是程序的正確性,在代碼的規(guī)范上并未加以注意,所以需要在重構(gòu)階段改善代碼。
  • 改進(jìn)軟件的設(shè)計(jì)。好的想法也并非一氣呵成,當(dāng)對(duì)以前的代碼有更好的解決方案時(shí),果斷進(jìn)行重構(gòu)來(lái)改進(jìn)軟件設(shè)計(jì)。
  • 查找Bug,提高質(zhì)量。良好的代碼不但能讓程序員易懂易于理解,同樣,也能方便程序員來(lái)發(fā)現(xiàn)問(wèn)題,修復(fù)問(wèn)題。測(cè)試與重構(gòu)是相輔相成的。
  • 提高編碼效率和編碼水平。重構(gòu)技術(shù)利于消除重復(fù)代碼,減少冗余代碼,提升程序員的編碼水平。程序員編碼水平的提升,同時(shí)也將體現(xiàn)在其編碼效率上。

2.何時(shí)應(yīng)該進(jìn)行重構(gòu)

那么,程序員應(yīng)該在何時(shí)進(jìn)行重構(gòu)呢?

  • 隨時(shí)重構(gòu)。也就是說(shuō),將重構(gòu)當(dāng)作是開發(fā)的一種習(xí)慣,重構(gòu)應(yīng)該與測(cè)試一樣自然。
  • 事不過(guò)三,三則重構(gòu)。當(dāng)代碼存在重復(fù)時(shí),就要進(jìn)行重構(gòu)了。
  • 添加新功能時(shí)。添加了新功能,對(duì)原有的代碼結(jié)構(gòu)進(jìn)行了調(diào)整,意味著需要重新進(jìn)行單元測(cè)試及重構(gòu)。
  • 修改錯(cuò)誤時(shí)。修復(fù)錯(cuò)誤后,同樣也是需要重新對(duì)接口進(jìn)行單元測(cè)試及重構(gòu)的。
  • 代碼審查。代碼審查是發(fā)現(xiàn)“代碼壞味道”非常好的時(shí)機(jī),自然也是進(jìn)行重構(gòu)的絕佳機(jī)會(huì)。

3.代碼的“壞味道”

如果一段代碼是不穩(wěn)定或有一些潛在問(wèn)題的,那么代碼往往會(huì)包含一些明顯的痕跡,就好像食物要腐壞之前,經(jīng)常會(huì)發(fā)出一些異味一樣,這些痕跡就是代碼“壞味道”。以下就是常見的代碼“壞味道”。

  • DuplicatedCode(重復(fù)代碼):重復(fù)是萬(wàn)惡之源。解決方法是將公共函數(shù)進(jìn)行提取。
  • LongMethod(過(guò)長(zhǎng)函數(shù)):過(guò)長(zhǎng)函數(shù)會(huì)導(dǎo)致責(zé)任不明確、難以切割、難以理解等一系列問(wèn)題。解決方法是將長(zhǎng)函數(shù)拆分成若干函數(shù)。
  • LargeClass(過(guò)大的類):會(huì)導(dǎo)致職責(zé)不明確、難理解。解決方法是拆分成若干類。
  • LongParameterList(過(guò)長(zhǎng)參數(shù)列):過(guò)長(zhǎng)參數(shù)列其實(shí)是沒有真正地遵從面向?qū)ο蟮木幋a方式,對(duì)于程序員來(lái)說(shuō)也是難以理解的。解決方法是將參數(shù)封裝成結(jié)構(gòu)或類。
  • DivergentChange(發(fā)散式變化):當(dāng)對(duì)多個(gè)需求進(jìn)行修改時(shí),都會(huì)動(dòng)到這種類。解決方法是對(duì)代碼進(jìn)行拆分,將總是一起變化的東西放在一起。
  • ShotgunSurgery(霞彈式修改):其實(shí)就是在沒有封裝變化處改動(dòng)一個(gè)需求,然后會(huì)涉及多個(gè)類被修改。解決方法是將各個(gè)修改點(diǎn)集中起來(lái),抽象成一個(gè)新類。
  • FeatureEnvy(依戀情結(jié)):一個(gè)類對(duì)其他類存在過(guò)多的依賴,比如某個(gè)類使用了大量其他類的成員,這就是FeatureEnvy。解決方法是將該類并到所依賴的類里面。
  • DataClumps(數(shù)據(jù)泥團(tuán)):數(shù)據(jù)泥團(tuán)是常一起出現(xiàn)的大堆數(shù)據(jù)。如果數(shù)據(jù)是有意義的,解決方法是就將結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)變?yōu)閷?duì)象。
  • PrimitiveObsession(基本類型偏執(zhí)):熱衷于使用int、long、String等基本類型。其解決方法是將其修改成使用類來(lái)替代。
  • SwitchStatements ( switch驚悚現(xiàn)身):當(dāng)出現(xiàn) switch語(yǔ)句判斷的條件太多時(shí),則要考慮少用switch語(yǔ)句,采用多態(tài)來(lái)代替。
  • ParallelInheritanceHierarchies(平行繼承體系):過(guò)多平行的類,使用類繼承并聯(lián)起來(lái)。解決方法是將其中一個(gè)類去掉繼承關(guān)系。
  • LazyClass(冗贅類):針對(duì)這些冗贅類,其解決方法是把這些不再重要的類里面的邏輯合并到相關(guān)類,并刪除舊的類。
  • SpeculativeGenerality(夸夸其談未來(lái)性):對(duì)于這些沒有用處的類,直接刪除即可。
  • TemporaryField (令人迷惑的暫時(shí)字段):對(duì)于這些字段,解決方法是將這些臨時(shí)變量集中到一個(gè)新類中去管理。
  • MessageChains(過(guò)度耦合的消息鏈):使用真正需要的函數(shù)和對(duì)象,而不要依賴于消息鏈。
  • MiddleMan(中間人):存在這種過(guò)度代理的問(wèn)題,其解決方法是用繼承替代委托。
  • InappropriateIntimacy(狎昵關(guān)系):兩個(gè)類彼此使用對(duì)方的private值域。解決方法是劃清界限拆散,或合并,或改成單項(xiàng)聯(lián)系。
  • AlternativeClasseswithDifferentInterfaces(異曲同工的類):這些類往往是相似的類,卻有不同的接口。解決方法是對(duì)這些類進(jìn)行重命名、移動(dòng)函數(shù)或抽象子類重復(fù)作用的類,從而合并成一個(gè)類。
  • IncompleteLibraryClass(不完美的庫(kù)類):解決方法是包一層函數(shù)或包成新的類。
  • DataClass(純稚的數(shù)據(jù)類):這些類很簡(jiǎn)單,往往僅有公共成員變量或簡(jiǎn)單的操作函數(shù)。解決方法是將相關(guān)操作封裝進(jìn)去,減少public成員變量。
  • RefusedBequest(拒絕遺贈(zèng)):這些類的表現(xiàn)是父類里面方法很多,但子類只用到有限幾個(gè)。解決方法是使用代理來(lái)替代繼承關(guān)系。
  • Comments(過(guò)多的注釋):注釋多了,就說(shuō)明代碼不清楚了。解決方法是寫注釋前先重構(gòu),去掉多余的注釋,“好代碼會(huì)說(shuō)話”。

4.減少測(cè)試的依賴

首先,我們必須承認(rèn),對(duì)象間的依賴無(wú)可避免。對(duì)象與對(duì)象之間通過(guò)協(xié)作來(lái)完成功能,任意一個(gè)對(duì)象都有可能用到另外對(duì)象的屬性、方法等成員。但同時(shí)也認(rèn)識(shí)到,代碼中的對(duì)象過(guò)度復(fù)雜的依賴關(guān)系往往是不提倡的,因?yàn)閷?duì)象之間的關(guān)聯(lián)性越大,意味著代碼改動(dòng)一處,影響的范圍就會(huì)越大,而這完全不利于系統(tǒng)的測(cè)試、重構(gòu)和后期維護(hù)。所以在現(xiàn)代軟件開發(fā)和測(cè)試過(guò)程中應(yīng)該盡量降低代碼之間的依賴。

相比于傳統(tǒng)JavaEE的開發(fā)模式,DI(依賴注人)使代碼更少地依賴容器,并削減了計(jì)算機(jī)程序的耦合問(wèn)題。通過(guò)簡(jiǎn)單的new操作,構(gòu)成程序員應(yīng)用的 POJO對(duì)象即可在JUnit或TestNG下進(jìn)行測(cè)試。即使沒有Spring或其他loC容器,也可以使用mock來(lái)模擬對(duì)象進(jìn)行獨(dú)立測(cè)試。清晰的分層和組件化的代碼將會(huì)促進(jìn)單元測(cè)試的簡(jiǎn)化。例如,當(dāng)運(yùn)行單元測(cè)試的時(shí)候,程序員可以通過(guò)stub或mock來(lái)對(duì)DAO或資源庫(kù)接口進(jìn)行替代,從而實(shí)現(xiàn)對(duì)服務(wù)層對(duì)象的測(cè)試,這個(gè)過(guò)程中程序員無(wú)須訪問(wèn)持久層數(shù)據(jù)。這樣就能減少對(duì)基礎(chǔ)設(shè)施的依賴。

在測(cè)試過(guò)程中,真實(shí)對(duì)象具有不可確定的行為,有可能產(chǎn)生不可預(yù)測(cè)的效果(如股票行情、天氣預(yù)報(bào)),同時(shí),真實(shí)對(duì)象存在以下問(wèn)題。

  • 真實(shí)對(duì)象很難被創(chuàng)建。
  • 真實(shí)對(duì)象的某些行為很難被觸發(fā)。
  • 真實(shí)對(duì)象實(shí)際上還不存在(和其他開發(fā)小組或和新的硬件打交道)等。

正是由于上面真實(shí)對(duì)象在測(cè)試的過(guò)程中存在的問(wèn)題,在測(cè)試中廣泛地采用mock測(cè)試來(lái)代替。

在單元測(cè)試上下文中,一個(gè)mock對(duì)象是指這樣的一個(gè)對(duì)象——它能夠用一些“虛構(gòu)的占位符”功能來(lái)“模擬”實(shí)現(xiàn)一些對(duì)象接口。在測(cè)試過(guò)程中,這些虛構(gòu)的占位符對(duì)象可用簡(jiǎn)單方式來(lái)模仿對(duì)于一個(gè)組件期望的行為和結(jié)果,從而讓程序員專注于組件本身的徹底測(cè)試,而不用擔(dān)心其他依賴性問(wèn)題。

mock對(duì)象經(jīng)常被用于單元測(cè)試。用mock對(duì)象來(lái)進(jìn)行測(cè)試,就是在測(cè)試過(guò)程中,對(duì)于某些不容易構(gòu)造(如HttpServletRequest必須在Servlet容器中才能構(gòu)造出來(lái))或不容易獲取的比較復(fù)雜的對(duì)象(如JDBC中的ResultSet對(duì)象),用一個(gè)虛擬的對(duì)象( mock對(duì)象)來(lái)創(chuàng)建以便測(cè)試的測(cè)試方法。

mock最大的功能是把單元測(cè)試的耦合分解開,如果編寫的代碼對(duì)另一個(gè)類或接口有依賴,它能夠模擬這些依賴,并驗(yàn)證所調(diào)用的依賴行為。

mock對(duì)象測(cè)試的關(guān)鍵步驟如下。

  • 使用一個(gè)接口來(lái)描述這個(gè)對(duì)象。
  • 在產(chǎn)品代碼中實(shí)現(xiàn)這個(gè)接口。
  • 在測(cè)試代碼中實(shí)現(xiàn)這個(gè)接口。
  • 在被測(cè)試代碼中只是通過(guò)接口來(lái)引用對(duì)象,所以它不知道這個(gè)引用的對(duì)象是真實(shí)對(duì)象,還是mock對(duì)象。

目前,在Java陣營(yíng)中主要的mock測(cè)試工具有Mockito、JMock、EasyMock 等。

5.mock與stub的區(qū)別

mock和 stub都是為了替換外部依賴對(duì)象,mock不是stub,兩者有以下區(qū)別。

  • 前者稱為mockist TDD,而后者一般稱為classic TDD。
  • 前者是基于行為的驗(yàn)證(Behavior Verification ),后者是基于狀態(tài)的驗(yàn)證(State Verification )。
  • 前者使用的是模擬的對(duì)象,而后者使用的是真實(shí)的對(duì)象。

現(xiàn)在通過(guò)一個(gè)例子來(lái)看看mock與 stub之間的區(qū)別。假如程序員要給發(fā)送mail的行為做一個(gè)測(cè)試,就可以像下面這樣寫一個(gè)簡(jiǎn)單的stub。

  1. //待測(cè)試的接口 
  2. public interface Mailservice(){ 
  3. public void send(Message msg); 
  4. /lstub測(cè)試類 
  5. public class MailServiceStub implements MailService i 
  6. private List<Message>messages = new ArrayList<Message>(); 
  7. public void send (Message msg){ 
  8. messages.add (msg); 
  9. public int numberSent( { 
  10. return messages.size(); 

也可以像下面這樣在stub 上使用狀態(tài)驗(yàn)證的測(cè)試方法。

  1. public class orserStateTester{ 
  2. Order order = new Order(TALISKER, 51); 
  3. MailServiceStub mailer = new MailserviceStub(); 
  4. order.setMailer(mailer); 
  5. order.fill (warehouse); 
  6. //通過(guò)發(fā)送的消息數(shù)來(lái)驗(yàn)證 
  7. assertEquals(1 , mailer.numberSent();} 

當(dāng)然這是一個(gè)非常簡(jiǎn)單的測(cè)試,只會(huì)發(fā)送一條message。在這里程序員還沒有測(cè)試它是否會(huì)發(fā)送給正確的人員或內(nèi)容是否正確。

如果使用mock,那么這個(gè)測(cè)試看起來(lái)就不太一樣了。

  1. lass OrderInteractionTester. .. 
  2. public void testorderSendsMail工fUnFilled() { 
  3. Order order =new Order (TALISKER ,51); 
  4. Mock warehouse = mock(Warehouse.class); 
  5. Mock mailer = mock(MailService.class); 
  6. order.setMailer((Mailservice)mailer.proxy()); 
  7. order.expects(once()).method ("hasInventory").withAnyArgument() 
  8. .will(returnvalue(false)); 
  9. order.fill((Warehouse) warehouse.proxy() 

在這兩個(gè)例子中,使用了stub和mock來(lái)代替真實(shí)的MailService對(duì)象。所不同的是,stub使用的是狀態(tài)確認(rèn)的方法,而mock使用的是行為確認(rèn)的方法。

想要在stub中使用狀態(tài)確認(rèn),需要在stub中增加額外的方法來(lái)協(xié)助驗(yàn)證。因此stub實(shí)現(xiàn)了MailService但是增加了額外的測(cè)試方法。

十年架構(gòu)師耗盡心血帶你如何進(jìn)行微服務(wù)的單元、集成和系統(tǒng)測(cè)試?

 

微服務(wù)的集成測(cè)試

集成測(cè)試也稱組裝測(cè)試或聯(lián)合測(cè)試,可以說(shuō)是單元測(cè)試的邏輯擴(kuò)展。它最簡(jiǎn)單的形式是把兩個(gè)已經(jīng)測(cè)試過(guò)的單元組合成一個(gè)組件,測(cè)試它們之間的接口。從使用的基本技術(shù)上來(lái)講,集成測(cè)試與單元測(cè)試在很多方面都很相似。程序員可以使用相同的測(cè)試運(yùn)行器和構(gòu)建系統(tǒng)的支持。集成測(cè)試和單元測(cè)試一個(gè)比較大的區(qū)別在于,集成測(cè)試使用了相對(duì)較少的mock。

例如,在涉及數(shù)據(jù)訪問(wèn)層的測(cè)試時(shí),單元測(cè)試會(huì)簡(jiǎn)單地模擬從后端數(shù)據(jù)庫(kù)返回的數(shù)據(jù)。而集成測(cè)試時(shí),測(cè)試過(guò)程中則會(huì)采用一個(gè)真實(shí)的數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)是一個(gè)需要測(cè)試資源類型及能暴露問(wèn)題的極好的例子。

在微服務(wù)架構(gòu)的集成測(cè)試中,程序員更加關(guān)注的是服務(wù)測(cè)試。

1.服務(wù)接口

在微服務(wù)的架構(gòu)中,服務(wù)接口大多以RESTfulAPI的形式加以暴露。REST是面向資源的,使用HTTP協(xié)議來(lái)完成相關(guān)通信,其主要的數(shù)據(jù)交換格式為JSON,當(dāng)然也可以是XML、HTML、二進(jìn)制文件等多媒體類型。資源的操作包括獲取、創(chuàng)建、修改和刪除資源,它們都可以用HTTP協(xié)議的GET、POST、PUT和DELETE方法來(lái)映射相關(guān)的操作。

在進(jìn)行服務(wù)測(cè)試時(shí),如果只想對(duì)單個(gè)服務(wù)功能進(jìn)行測(cè)試,那么為了對(duì)其他相關(guān)的服務(wù)進(jìn)行隔離,則需要給所有的外部服務(wù)合作者進(jìn)行打樁。每一個(gè)下游合作者都需要一個(gè)打樁服務(wù),然后在進(jìn)行服務(wù)測(cè)試的時(shí)候啟動(dòng)它們,并確保它們是正常運(yùn)行的。程序員還需要對(duì)被測(cè)試服務(wù)進(jìn)行配置,保證能夠在測(cè)試過(guò)程中連接到這些打樁服務(wù)。同時(shí),為了模仿真實(shí)的服務(wù),程序員還需要配置打樁服務(wù),為被測(cè)試服務(wù)的請(qǐng)求發(fā)回響應(yīng)。

下面是一個(gè)采用Spring 框架實(shí)現(xiàn)的關(guān)于“用戶車輛信息”測(cè)試接口的例子。

  1. import org.junit.*; 
  2. import org.junit.runner.*; 
  3. import org.springframework.beans.factory.annotation.*; 
  4. import org.springframework.boot.test.autoconfigure.web.servlet.*; 
  5. import org.springframework.boot.test.mock.mockito.*; 
  6. import static org.assertj.core.api.Assertions.*; 
  7. import static org.mockito.BDDMockito.*; 
  8. import static org.springframework.test.web.servlet.request.MockMvc 
  9. RequestBuilders.*; 
  10. import static org.springframework.test.web.servlet.result.MockMvc 
  11. ResultMatchers.*; 
  12. @RunWith(SpringRunner.class) 
  13. @WebMvcTest(UserVehicleController.class) 
  14. public class MyControllerTests{ 
  15. @Autowired 
  16. private MockMvc mvc; 
  17. @MockBean 
  18. private UserVehicleService userVehicleService; 
  19. @Test 
  20. public void testExample( throws Exception { 
  21. given(this.userVehicleService.getVehicleDetails("sboot")) 
  22. .willReturn(new VehicleDetails("BMW","X7")); 
  23. this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_ 
  24. PLAIN)) 
  25. .andExpect(status().isok()).andExpect(content(). 
  26. string("BMW x7")); 

在該測(cè)試中,程序員用mock模擬了/sboot/vehicle接口的數(shù)據(jù)VehicleDetails("BMW","X7"),并通過(guò)MockMvc來(lái)進(jìn)行測(cè)試結(jié)果的判斷。

2.客戶端

有非常多的客戶端可以用于測(cè)試RESTful服務(wù)。可以直接通過(guò)瀏覽器來(lái)進(jìn)行測(cè)試,如在本書前面介紹過(guò)的RESTClient、Postman等。很多應(yīng)用框架本身提供了用于測(cè)試RESTful API的類庫(kù),如Java平臺(tái)的像Spring的RestTemplate 和像Jersey的Client API等,.NET平臺(tái)的RestSharp ( http:1restsharp.org)等。也有一些獨(dú)立安裝的REST測(cè)試軟件,如SoapUI ( ttps:/www.soapui.org ),當(dāng)然最簡(jiǎn)潔的方式莫過(guò)于使用cURL在命令行中進(jìn)行測(cè)試。

下面是一個(gè)測(cè)試Elasticsearch是否啟動(dòng)成功的例子,可以在終端直接使用cURL來(lái)執(zhí)行以下操作。

  1. scurl 'http://localhost:9200/?pretty' 

cURL提供了一種將請(qǐng)求提交到Elasticsearch的便捷方式,然后可以在終端看到與下面類似的響應(yīng)。

  1. "cluster name""elasticsearch"
  2. "cluster uuid" :"uqcQAMTtTIO6CanROYgveQ"
  3. "version":{ 
  4. "number""5.5.0", 
  5. "build_hash":"260387d" , 
  6. "build_date":"2017-06-30T23:16:05.735Z"", 
  7. "build_snapshot" :false
  8. "lucene version":"6.6.O" 
  9. }, 
  10. "tagline":"You Know, for Search" 

微服務(wù)的系統(tǒng)測(cè)試

引入微服務(wù)架構(gòu)之后,隨著微服務(wù)數(shù)量的增多,測(cè)試用例也隨之增多,測(cè)試工作也越來(lái)越依賴于測(cè)試的自動(dòng)化。Maven或Gradle等構(gòu)建工具,都會(huì)將測(cè)試納入其生命周期內(nèi),所以,只要寫好相關(guān)的單元測(cè)試用例,單元測(cè)試及集成測(cè)試就能在構(gòu)建過(guò)程中自動(dòng)執(zhí)行,構(gòu)建完成之后,也可以馬上看到測(cè)試報(bào)告。

在系統(tǒng)測(cè)試階段,除了自動(dòng)化測(cè)試外,手工測(cè)試仍然是無(wú)法避免的。Docker等容器為自動(dòng)化提供了基礎(chǔ)設(shè)施,也為手工測(cè)試帶來(lái)了新的變革。

在基于容器的持續(xù)部署流程中,軟件會(huì)經(jīng)歷最終被打包成容器鏡像,從而可以部署到任意環(huán)境而無(wú)須擔(dān)心工作變量不一致所帶來(lái)的問(wèn)題。進(jìn)入部署階段意味著集成測(cè)試及單元測(cè)試都已經(jīng)通過(guò)了。

但這顯然并不是測(cè)試的全部,很多測(cè)試必須要在上線部署后才能進(jìn)行,如一些非功能性的需求。

同時(shí),用戶對(duì)于需求的期望是否與最初的設(shè)計(jì)相符,這個(gè)也必須要等到產(chǎn)品上線后才能驗(yàn)證。所以,上線后的測(cè)試工作仍然是非常重要的。

1.冒煙測(cè)試

所謂冒煙測(cè)試,是指對(duì)一個(gè)新編譯的軟件版本在需要進(jìn)行正式測(cè)試前,為了確認(rèn)軟件基本功能是否正常而進(jìn)行的測(cè)試。軟件經(jīng)過(guò)冒煙測(cè)試之后,才會(huì)進(jìn)行后續(xù)的正式測(cè)試工作。冒煙測(cè)試的執(zhí)行者往往是版本編譯人員。

由于冒煙測(cè)試耗時(shí)短,并且能夠驗(yàn)證軟件大部分主要的功能,因此在進(jìn)行CI/CD每日構(gòu)建過(guò)程中,都會(huì)執(zhí)行冒煙測(cè)試。

⒉藍(lán)綠部署

藍(lán)綠部署通過(guò)部署新舊兩套版本來(lái)降低發(fā)布新版本的風(fēng)險(xiǎn)。其原理是,當(dāng)部署新版本后(綠部署),老版本(藍(lán)部署)仍然需要保持在生產(chǎn)環(huán)境中可用一段時(shí)間。如果新版本上線,測(cè)試沒有問(wèn)題后,那么所有的生產(chǎn)負(fù)荷就會(huì)從舊版本切換到新版本中。

以下是一個(gè)藍(lán)綠部署的例子。其中,vl代表的是服務(wù)的舊版本(藍(lán)色),v2代表的是新版本(綠色),如圖4-2所示。

十年架構(gòu)師耗盡心血帶你如何進(jìn)行微服務(wù)的單元、集成和系統(tǒng)測(cè)試?

 

這里面有以下幾個(gè)注意事項(xiàng)。

  • 藍(lán)綠兩個(gè)部署環(huán)境是一致的,并且兩者應(yīng)該是完全隔離的(可以是不同的主機(jī)或不同的容器)。
  • 藍(lán)綠環(huán)境兩者之間有一個(gè)類似于切換器的裝置用于流量的切換,如可以是負(fù)載均衡器、反向代理或路由器。
  • 新版本(綠部署)測(cè)試失敗后,可以馬上回溯到舊版本。
  • 藍(lán)綠部署經(jīng)常與冒煙測(cè)試結(jié)合使用。
  • 實(shí)施藍(lán)綠部署,整個(gè)過(guò)程是自動(dòng)化處理的,用戶并不會(huì)感覺到任何宕機(jī)或服務(wù)重啟。

3.A/B測(cè)試

A/B測(cè)試是一種新興的軟件測(cè)試方法。A/B測(cè)試本質(zhì)上是將軟件分成A、B兩個(gè)不同的版本來(lái)進(jìn)行分離實(shí)驗(yàn)。AB測(cè)試的目的在于通過(guò)科學(xué)的實(shí)驗(yàn)設(shè)計(jì)、采樣樣本、流量分割與小流量測(cè)試等方式來(lái)獲得具有代表性的實(shí)驗(yàn)結(jié)論,并確保該結(jié)論在推廣到全部流量之前是可信賴的。例如,在經(jīng)過(guò)一段時(shí)間的測(cè)試后,實(shí)驗(yàn)結(jié)論顯示,B版本的用戶認(rèn)可度較高,于是,線上系統(tǒng)就可以更新到B版本上來(lái)。

4.金絲雀發(fā)布

金絲雀發(fā)布是增量發(fā)布的一種類型,它的執(zhí)行方式是在原有軟件生產(chǎn)版本可用的情況下,同時(shí)部署一個(gè)新的版本。這樣,部分生產(chǎn)流量就會(huì)引流到新部署的版本,從而來(lái)驗(yàn)證系統(tǒng)是否按照預(yù)期的內(nèi)容執(zhí)行。這些預(yù)期的內(nèi)容可以是功能性的需求,也可以是非功能性的需求。例如,程序員可以驗(yàn)證新部署的服務(wù)的請(qǐng)求響應(yīng)時(shí)間是否在1秒以內(nèi)。

如果新版本沒有達(dá)到預(yù)期的效果,那么可以迅速回溯到舊版本上去。如果達(dá)到了預(yù)期的效果,那么可以將生產(chǎn)流量更多地引流到新版本上去。

金絲雀發(fā)布與A/B測(cè)試非常類似,兩者往往結(jié)合使用。而與藍(lán)綠部署的差異在于,金絲雀發(fā)布新舊版本并存的時(shí)間更長(zhǎng)久一些。 

 

責(zé)任編輯:龐桂玉 來(lái)源: 今日頭條
相關(guān)推薦

2020-01-14 14:37:29

JVMJava體系

2023-03-24 16:18:08

微服務(wù)架構(gòu)

2019-02-22 10:00:45

Java開發(fā)代碼

2019-07-30 09:10:06

工程師Java技術(shù)

2019-09-02 09:21:16

Zookeeper架構(gòu)師集群

2023-12-11 08:25:15

Java框架Android

2023-01-09 07:32:27

架構(gòu)微服務(wù)轉(zhuǎn)型

2024-03-29 08:03:48

單元測(cè)試流量

2020-11-25 09:56:48

架構(gòu)運(yùn)維技術(shù)

2022-03-28 11:41:21

物聯(lián)網(wǎng)物聯(lián)網(wǎng)市場(chǎng)智能電網(wǎng)

2021-06-22 18:00:09

微服務(wù)架構(gòu)系統(tǒng)

2023-10-07 08:49:56

測(cè)試驅(qū)動(dòng)開發(fā)Xunit 框架

2022-12-27 07:57:43

2023-04-12 16:25:00

谷歌人工智能

2019-07-22 22:22:02

架構(gòu)運(yùn)維技術(shù)

2022-03-18 13:46:20

物聯(lián)網(wǎng)數(shù)據(jù)技術(shù)

2021-04-19 08:25:03

架構(gòu)師公司系統(tǒng)

2019-02-26 12:40:10

程序員架構(gòu)師阿里

2023-09-03 23:49:35

2009-12-15 10:24:32

Visio 2008架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩免费中文字幕 | 91精品国产欧美一区二区成人 | 日本a v在线播放 | 日韩一区二区在线视频 | 看真人视频一级毛片 | 久久成人国产 | 欧洲精品一区 | 午夜精品一区二区三区在线视频 | 日本精品一区二区三区在线观看 | 一级欧美 | 色婷综合网| 人人射人人| 久久久久久99 | 欧美日韩高清免费 | 狠狠干天天干 | 亚洲h在线观看 | 欧美在线高清 | 国产日韩欧美精品 | 日日夜精品视频 | 国产日韩精品视频 | 亚洲欧美一区二区三区国产精品 | 97伦理电影 | 全免费a级毛片免费看视频免费下 | 一区二区精品视频 | 91成人在线视频 | 欧美三区在线观看 | 久久久久国产一级毛片 | 亚洲福利一区 | 国产成人av一区二区三区 | 亚洲欧美精品久久 | 欧美成人激情 | 天天操夜夜操免费视频 | 婷婷久久五月 | 香蕉视频久久久 | 久草热线 | 久久新 | 精品视频久久久久久 | 一区二区三区av | 一区二区三区视频在线观看 | 亚洲精品乱码久久久久v最新版 | 午夜影院免费体验区 |