合同測試簡介 - Elizabeth Fiennes

banq發表於2019-01-16

合同測試是對部署或模擬服務端點的詢問,以在部署之前獲取資訊或在測試中定義端點。

術語
服務消費者:向另一個元件發起HTTP請求的元件。
服務提供者:響應來自其他元件的HTTP請求的伺服器。
< - 總的來說,請求和響應對稱為互動 - >
服務廣告:服務使用者透過嵌入或呈現機器可理解的Web服務描述來廣告(提供)Web服務的方法。
合同檔案:包含在使用者測試中定義的JSON序列化互動(請求和響應)。
模擬服務提供商:消費者測試用於模擬實際的服務提供者,這意味著可以執行類似整合的測試而無需實際的服務提供者。
服務協議:服務提供者在服務使用者提供特定請求後返回特定響應的承諾。
內部服務消費者:這是貴公司的另一個系統,它將您的服務用於身份驗證,審計許可權或資料等事務。
外部服務消費者:這是您公司外部的一方,它將您的服務作為其技術產品的一部分進行消費

怎麼做?
由於合同測試是一種測試服務的方法,因此有三種方法:

  • 針對已部署的服務(URL)
  • 針對模擬服務(程式碼)
  • 針對待定服務(無)

部署是王道:對已部署的服務進行測試將是一種建議的方法,以確保在進行開發更改後,服務(例如API提供者和客戶端)仍可以相互通訊。

在針對模擬進行測試時,它可以替代某些昂貴/耗時/脆弱的整合測試。關於後一點,值得一提的是合同測試不能完全取代整合測試。

當針對尚待開發的API進行測試時,測試將全部失敗,因為他們“指向”空氣。在編寫測試時,它們可以用作在測試驅動開發(TDD)中工作的團隊的對話和設計決策的管道。在編寫端點時,測試將透過並驗證提供商的合同是否已經完成。

什麼方式?
1.瞭解你的角色:
您是提供者還是消費者?您的消費是內部還是外部關注?如果您是提供者,則需要檢視所有端點和內部整合。如果您是消費者(面向外部),您可能只是在檢視您消耗的端點而不是每個端點。
並不是說我們沒有具體的答案,只是我們需要大量的資訊和背景才能給你正確的答案。

2. API文件
為了在部署的服務上或透過模擬進行合同測試,必須向所有各方提供合同。這是我們的API文件。根據組織的REST成熟度,其質量可能會有所不同。
符合REST Richardson成熟度模型(RMM)3級的API釋出者將透過端點響應公開合同宣告,無論是真實的還是模擬的。大多數提供商都在RMM Level 2上生成API,因此提供準確的文件更為重要。有許多工具可以自動生成針對已知標準定義的API的文件 - OpenAPI / Swagger,RAML或API Blueprint。

3.測試工具
在構建合同測試時,您可以使用許多工具,具體取決於您要進行的測試的範圍和視角。PACT適用於內部提供商和以消費者為中心的測試。對於那些專注於消費者測試的人,建議使用Spring雲合約Hoverfly是用Go編寫的,具有對Java的本機支援,可以在JUnit測試中執行。Hoverfly可用於測試REST API以及測試微服務之間的呼叫。

4.定義您的測試範圍
開發人員和測試人員很難解決的一件事是他們應該在測試過程中對功能的深入瞭解。這實際上取決於您希望從測試中獲得的資訊級別,它們所針對的資訊以及您作為提供者或消費者的觀點。以下是一些建議的範圍,但它們並非詳盡無遺,與一般的合同測試一樣,您必須考慮哪種方法適合您以及您最好的工作環境。

一些測試 - 資料輸入/部署的端點/順序功能/改變資料狀態
首先我們可以POST一個新的寵物:

POST "https://petstore.swagger.io/v2/pet" -H "accept: application/xml" -H "Content-Type: application/json" -d "{ \"id\": 0, \"category\": { \"id\": 0, \"name\": \"string\" }, \"name\": \"Dinosaur\", \"photoUrls\": [ \"string\" ], \"tags\": [ { \"id\": 0, \"name\": \"string\" } ], \"status\": \"available\"}"


根據上面POST請求中提供的資料,我們可以將其餘的請求作為測試來排序,以獲取預期的資料。快樂的狩獵!

PUT /pet //Updates the pet
GET /pet/findByStatus //Finds Pets by status
GET /pet/findByTags //Finds Pets by tags
GET /pet/{petId} //Find pet by ID
POST /pet/{petId} //Updates a pet in the store with form data
DELETE /pet/{petId} //Deletes a pet
POST /pet/{petId}/uploadImage //uploads an image


使用cURL對GET / Pets端點執行一些檢查

**測試:**
獲取一個不存在的端點,以確保服務可以乾淨地處理這個端點並提醒我們我們嘗試使用的任何不正確的端點。(是的 - 這是一個頑皮的測試,因為Petstore沒有將此響應稱為支援)

請求(在cURL中):(
GET -I -X "https://petstore.swagger.io/v2/pet/
-I開關將確保cURL輸出響應

響應:

HTTP/1.1 405 Method Not Allowed
Date: Thu, 20 Dec 2019 14:16:29 GMT
Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: GET, POST, DELETE, PUT 
Access-Control-Allow-Headers: A, B, C, D 
Content-Type: application/json 
Connection: close 
Server: Betty Boo 


**測試:**
為存在的端點獲取生成的STATUS端點
請求: 

C:\DEV\cURL\bin>curl -I -X GET "https://petstore.swagger.io/v2/pet/findByStatus?status=BLAH"


響應: 

HTTP/1.1 200 OK 
Date: Thu, 20 Dec 2019 14:16:29 GMT
Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: GET, POST, DELETE, PUT 
Access-Control-Allow-Headers: A, B, C, D 
Content-Type: application/json 
Connection: close 
Server: Betty Boo 


模擬端點/ TDD - 經典或倫敦學校
關於TDD的另一種方式已經寫了很多,而這裡沒有重複。它還伴隨著一大堆爭論,採取TDD還是合同測試討論。對於想要更詳細地研究這個內容的人,如果您想研究檢視基於角色的測試重點的演算法經驗的方式和方法,我提供了連結以提供更多上下文。 倫敦學校芝加哥學院

從測試中獲得了哪些資訊?
對已部署服務的良好合同測試將告訴您是否:
*正在測試的API瞭解其所做的請求
*正在測試的API可以傳送預期的響應
*端點可訪問
*提供者和消費者有工作連線,如果您正在測試已部署的服務
*如果預期的整合已到位

同樣可以說對於模擬和TDD合同測試,只有在部署的服務版本對應於模擬和測試時。因此,應使用模擬和TDD測試來推動設計決策,而不是提供資訊。

合同測試可以測試什麼?
任何研究合同測試的人都會在合同測試的使用和界限上找到大量相互矛盾的資訊。我不打算明確說明是否進行的合同測試以及在什麼情況下適合。

如果您正在為測試模擬API端點,那麼合同測試將不會向您提供有關最終部署的端點的任何資訊。如果要查詢端點配置問題或誤用類等潛在問題,則需要針對已部署的服務執行一些獨立或整合測試。

如果您有關於資料的規則,例如最大和最小邊界,格式和大小。除非您正在測試部署的服務版本,否則合同測試不會以有效的方式測試這些規則。

無法測試的指標
協議是被測服務提供的API規範。因此,無法測試該規範中未描述的任何功能。這包括:
*基於客戶的工作流程
*一些UI功能
*服務水平協議(SLA)
*故障轉移計劃
*壓力下的效能
*部署環境的適用性

如果您的內部或外部消費者希望能夠以合同中未記錄的方式使用您的服務,那麼您們都無法對此進行測試,除非它被編寫為期望失敗的未來狀態測試在第一次執行。這就是為什麼在測試任何請求/響應對開始之前確保共享是很重要的原因。 

合同測試不可以測試什麼?
基於合同的單元測試僅檢查API端點連線是否處於活動狀態並正常執行(響應)。合同測試確保服務按照協議的標準做出響應。為了提供一個協議的例項,我將使用Swagger Petstore API端點 -
根據規範,Petstore API將返回200以查詢要求其查詢狀態為“可用”,“待定”或“已售出”的任何查詢。對於其他任何東西,它將返回400.有關http請求和響應的更多資訊 - 請檢視此處。我們來測試這個協議:
如果我傳送了請求: 
GET https://petstore.swagger.io/v2/pet/findByStatus?status=available
=>我應該收到200響應,因為這是一個有效的請求。Petstore支援“可用”狀態

GET https://petstore.swagger.io/v2/pet/findBySize
=>我應該得到400響應,因為這是一個無效的請求。由於Petstore`不支援“findbysize”選項

您可以使用Swagger'Try it out'功能,cURL或Postman來玩Petstore請求。請記住,swagger.io介面僅測試快樂路徑,因此您需要使用其他工具之一傳送請求語法以呼叫400/500型別響應。

如何將合同測試納入我的整體方法?
儘量不要將合同測試視為單元測試,獨立API功能測試或整合測試的替代,它更像是一個免費的測試流。只要您可以避免在測試和測試的不同階段重複測試儘可能接近程式碼。

1.獨立的API功能測試 
當我能夠推薦合同測試時,我最常問的問題是“oooh可以替代獨立的API測試嗎?答案是肯定的......沒有。如果您在可以訪問的環境中測試已部署的API,則合同測試肯定會驗證API是否按預期工作。但是,如果您正在模擬端點,作為內部或外部使用者,您無法替換此測試,尤其是如果測試結果有可能導致合同發生變化,那麼部署與模擬的內容不同。

2.整合測試
合同測試無法找到非邏輯缺陷,例如負面測試暴露的異常,也無法檢測資料庫條目或連線的配置問題。 

這是整合測試(或端到端測試)發揮作用的地方。如果您已經完成了合同測試(並且您應該儘可能早地在開發週期中進行測試),那麼您可以確保您的服務端點正在處理請求並按預期進行響應但是如果計劃的部署將會有效與它的整合服務/資料庫/認證系統等。 還值得記住的是,合同測試會告訴您存在中斷但不一定中斷的地方與獨立測試或整合測試相同。 

用例
用例1 - 沒有開發服務的內部消費者

我是TeamA(消費者)的測試人員。TeamB(提供商)將開發一種新服務,我測試的元件必須與之整合。我想寫一些測試來確保兩者之間的整合。與TeamA和TeamB的開發人員合作,我將針對新服務針對模擬端點編寫一些合同測試,以確保在我的元件廣告端點時,它們將按預期進行整合。 

用例2 - 具有開發服務的外部消費者
我是一名網路開發人員,在我的漫畫書店店面消費漫威漫畫API。我想確保對Marvel API的任何更改都不會破壞我所宣傳的服務,因為這會破壞我的目標網頁的幾個部分。我將為我的測試人員提供API規範,以便我們可以模擬API。由此產生的合同測試將幫助我們驗證在對服務URL或單個端點進行任何更改後,我們期望Marvel作為我們的提供商的所有協議仍然存在。

用例3 - 生產中具有端點的內部消費者​​​​​​​
我們是一個Scrum團隊。我們已經構建了一個新元件來替換已經在生產中的元件。元件使用的API也在生產中,但除了內部開發團隊之外的任何人都不能使用。我們不希望為這一個變化構建一個完整的迴歸環境,因為我們有能力在生產中進行測試。但是,我們確實希望保證部署的元件可以在部署到實時之前訪問它所宣傳的所有端點。我們將模擬現有的端點,並透過合同測試確保我們的新元件可以使用它們。 

用例4 - 做出哪些技術設計決策
我們是一個Scrum團隊。我們打算為基於雲的容器構建和部署新API。但是,團隊內部是否存在使用REST或SOAP服務的爭論。雙方都有好處使用。我們決定對這兩者進行POC,並瞭解API在功能級別上的響應能力。這意味著我們將監視對API呼叫的響應的SLA時間。如果從第一次呼叫到響應的響應時間超過100毫秒,我們編寫測試並輸入一個宣告為失敗的斷言的子句。透過這種方式,我們將瞭解應用程式中的快樂路徑,哪些功能在相同環境中具有最高效能,但具有不同的服務設計。 

​​​​​​​
 

相關文章