版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 契約測試框架-Pact實(shí)踐dotNET跨平臺 微信號 opendotnet功能介紹 在這里你可以談微軟.NET,Mono的跨平臺開發(fā)技術(shù),也可以談?wù)勂渌目缙脚_技術(shù)。 在這里可以讓你的.NET項(xiàng)目有新的思路,不局限于微軟的技術(shù)棧,橫跨Windows,Linux 主流平臺本文將介紹一個開源的契約測試框架Pact,它最初是用ruby語言實(shí)現(xiàn)的,后來被js,C#,java,go,python 等語言重寫,此文將介紹Pact框架的相關(guān)知識并結(jié)合示例代碼講解在實(shí)際項(xiàng)目中應(yīng)該怎么使用。Pact是什么?Pact是一個開源框架,最早是由澳洲最大的房地產(chǎn)信息提供商REA Group的開發(fā)者及咨詢師們共同創(chuàng)造。
2、REA Group的開發(fā)團(tuán)隊(duì)很早便在項(xiàng)目中使用了微服務(wù)架構(gòu),并在團(tuán)隊(duì)中對于敏捷和測試的重要性早已形成共識,因此設(shè)計(jì)出這樣的優(yōu)秀框架并應(yīng)用于日常工作中也是十分自然。Pact工具于2013年開始開源,發(fā)展到今天已然形成了一個小的生態(tài)圈,包括各種語言(Ruby/Java/.NET/JavaScript/Go/Scala/Groovy.)下的Pact實(shí)現(xiàn),契約文件共享工具Pact Broker等。Pact的用戶已經(jīng)遍及包括RedHat、IBM、Accenture等在內(nèi)的若干知名公司,Pact已經(jīng)是事實(shí)上的契約測試方面的業(yè)界標(biāo)準(zhǔn)。Pact可以用來做什么?Pact是支持消費(fèi)者驅(qū)動的契約測試框架,針對微服務(wù)
3、的模式下多個單獨(dú)服務(wù)的接口契約測試以及前后端分離的模式提供了很好的支持。Pact的工作原理消費(fèi)者端作為數(shù)據(jù)的最終使用者非常清楚,明確的知道需要的什么樣格式,類型的數(shù)據(jù),它將負(fù)責(zé)創(chuàng)建契約文檔(包含結(jié)構(gòu)和格式的json文件),服務(wù)提供端將根據(jù)消費(fèi)者端創(chuàng)建的契約文檔提供對應(yīng)格式的數(shù)據(jù)并返回給消費(fèi)者,通過契約檢查判斷如果服務(wù)端提供的數(shù)據(jù)和消費(fèi)者生成的契約不匹配,將拋出異常并提示給服務(wù)端??偨Y(jié)如下:在消費(fèi)者項(xiàng)目代碼中編寫單元測試,期望響應(yīng)設(shè)置于模擬的服務(wù)提供者上。在測試運(yùn)行時,模擬的服務(wù)將返回所期望的響應(yīng)。請求和所期望的響應(yīng)將會被寫入到一個“pact”文件中。pact文件中的請求隨后在提供者上進(jìn)行重放,
4、并檢查實(shí)際響應(yīng)以確保其與所期望響應(yīng)相匹配。Pact相關(guān)的術(shù)語 服務(wù)消費(fèi)者服務(wù)消費(fèi)者是指向另一組件(服務(wù)提供者)發(fā)起HTTP請求的組件。注意這并不依賴于數(shù)據(jù)的發(fā)送方式無論是GET還是PUT/POST/PATCH,消費(fèi)者都是HTTP請求的發(fā)起者。服務(wù)提供者服務(wù)提供者是指向另一組件(服務(wù)消費(fèi)者)的HTTP請求提供響應(yīng)的服務(wù)器。 模擬服務(wù)提供者模擬服務(wù)提供者用于在消費(fèi)者項(xiàng)目中的單元測試?yán)锬M真實(shí)的服務(wù)提供者,意味著不必需要真實(shí)的服務(wù)提供者就緒,就可以將類集成測試運(yùn)行起來。Pact文件Pact文件是指一個含有消費(fèi)者測試中所定義的請求和響應(yīng)被序列化后的JSON的文件,即契約。 Pact驗(yàn)證(契約驗(yàn)證)要對
5、一個Pact進(jìn)行驗(yàn)證,就要對Pact文件中所包含的請求基于提供者代碼進(jìn)行重放,然后檢查返回的響應(yīng),確保其與Pact文件中所期望響應(yīng)相匹配。 提供者狀態(tài)在對提供者重放某個給定的請求時,一個用于描述此時提供者應(yīng)具有的“狀態(tài)”(類似于夾具)的名字比如“when user ken does not exists”或“when user ken has a bank account”。提供者狀態(tài)的名字是在寫消費(fèi)者測試時被指定的,之后當(dāng)運(yùn)行提供者的pact驗(yàn)證時,這個名字將被用于唯一標(biāo)識在請求執(zhí)行前應(yīng)運(yùn)行的代碼塊。Pact適用的場景 當(dāng)你的團(tuán)隊(duì)同時負(fù)責(zé)開發(fā)服務(wù)消費(fèi)者與服務(wù)提供者,并且服務(wù)消費(fèi)者的需求被用來
6、驅(qū)動服務(wù)提供者的功能時,Pact對于在服務(wù)集成方面進(jìn)行設(shè)計(jì)和測試是最具價(jià)值 的。它是組織內(nèi)部 開發(fā)和測試微服務(wù),前后端分離項(xiàng)目的絕佳工具。Pact不適用的場景性能和壓力測試。服務(wù)提供者的功能測試這是服務(wù)提供者自己的測試應(yīng)該做的。Pact是用來檢查請求和響應(yīng)的內(nèi)容及格式。當(dāng)你在必須使用實(shí)際測試的API才能將數(shù)據(jù)載入服務(wù)提供者的情況下,因?yàn)槟愕姆?wù)提供者中存在了無法mock的第三方的依賴“透傳”API的測試,是指服務(wù)提供者僅將請求內(nèi)容傳遞到下游服務(wù)而不做任何驗(yàn)證。Pact使用實(shí)例下面將展示代碼示例,這是一個前后端分離的項(xiàng)目,前端使用javascript訪問后端api獲取數(shù)據(jù),后端使用.net We
7、bApi 提供數(shù)據(jù)的返回后端代碼:新建BookingController,返回一個預(yù)定對象的信息,訪問地址:http:/localhost:51502/api/bookingpublic class BookingController : ApiController / GET: Booking HttpGet public BookingModel Get() return new BookingModel() Id = 12, FirstName = Ken, LastName = Wang, Users = new List() new User() Name = asd, Age =
8、1 , new User() Name = asd, Age = 1 , new User() Name = kenwang, Age = 223, Address = shangxi road ; BookingModel 實(shí)體定義如下:publicclassBookingModelpublicintId get;set; publicstringFirstName get;set; publicstringLastName get;set; publicList Users get;set; publicclassUserpublicstringName get;set; publicst
9、ringAge get;set; publicstringAddress get;set; 返回對象格式如下:Id: 12,FirstName:Ken,LastName:Wang,Users: Name:asd,Age:1,Address: 0,Name:asd,Age:1,Address: 0,Name:kenwang,Age:223,Address:shanxi road服務(wù)端就好了,下面看消費(fèi)端實(shí)現(xiàn)client.js 負(fù)責(zé)發(fā)起調(diào)用請求來獲取數(shù)據(jù):const request = require(superagent)const API_HOST = process.env.API_HOST
10、 | http:/localhostconst API_PORT = 51502const moment = require(moment)const API_ENDPOINT = $API_HOST:$API_PORT/ Fetch provider dataconst fetchProviderData = () = return request .get($API_ENDPOINT/api/booking) .then(res) = var Users = ; Users.push( Name: user1, Age : 11 ); Users.push( Name: asd, Age
11、: 1 ); return Id: 12, FirstName: ken, LastName: wang, Users: Users , (err) = throw new Error(Error from response: $err.body) )module.exports = fetchProviderDataconsumer.js負(fù)責(zé)調(diào)用client.js的方法獲取數(shù)據(jù),拿到數(shù)據(jù)之后記錄日志const client = require(./client)client.fetchProviderData().then(response = console.log(response),
12、error = console.error(error)添加client.js的測試代碼,前面的工作原理部分講到契約的生成是依賴于消費(fèi)者端的測試代碼而生成,也就是說消費(fèi)者端通過單元測試既覆蓋了代碼邏輯,又幫助我們生成了契約文件。consumerPact.spec.js文件是對client的測試:const chai = require(chai)const path = require(path)const chaiAsPromised = require(chai-as-promised)const pact = require(pact)const expect = chai.expect
13、const API_PORT = process.env.API_PORT | 51502const fetchProviderData = require(./client)chai.use(chaiAsPromised)/ Configure and import consumer API/ Note that we update the API endpoint to point at the Mock Serviceconst LOG_LEVEL = process.env.LOG_LEVEL | WARNconst provider = pact( consumer: Consume
14、r Demo, provider: Provider Demo, port: API_PORT, log: path.resolve(process.cwd(), logs, pact.log), dir: path.resolve(process.cwd(), pacts), logLevel: LOG_LEVEL, spec: 2)/ Alias flexible matchers for simplicityconst somethingLike: like,eachLike: eachLike, term = pact.Matchersdescribe(Pact with Our Pr
15、ovider, () = before() = return provider.setup() ) describe(given data count 0, () = describe(when a call to the Provider is made, () = describe(and a valid date is provided, () = before() = return provider.addInteraction( uponReceiving: a request for JSON data, withRequest: method: GET, path: /api/b
16、ooking , willRespondWith: status: 200, headers: Content-Type: application/json; charset=utf-8 , body: Id: like(10), FirstName: like(ken), LastName: like(wang), Users: eachLike( Name: like(test), Age: like(10) ,min:1) ) ) it(can process the JSON payload from the provider, done = const response = fetc
17、hProviderData() expect(response).perty(Id, 10) ) it(should validate the interactions and create a contract, () = return provider.verify() ) ) ) ) / Write pact files to file after() = return provider.finalize() )okay,消費(fèi)者端的代碼已經(jīng)完成,我們來執(zhí)行一下consumer.js,成功之后便會生成對應(yīng)的contract文件,如下: consumer: name: Consumer De
18、mo , provider: name: Provider Demo , interactions: description: a request for JSON data, providerState: data count 0, request: method: GET, path: /api/booking , response: status: 200, headers: Content-Type: application/json; charset=utf-8 , body: Id: 10, FirstName: ken, LastName: wang, Users: Name:
19、test, Age: 10 , matchingRules: $.body.Id: match: type , $.body.FirstName: match: type , $.body.LastName: match: type , $.body.Users: min: 1 , $.body.Users*.*: match: type , $.body.Users*.Name: match: type , $.body.Users*.Age: match: type , metadata: pactSpecification: version: 2.0.0 這就是需要消費(fèi)端需要的數(shù)據(jù)格式,
20、而作為服務(wù)提供者提供給消費(fèi)者的數(shù)據(jù)必須滿足這樣的約束,否則就是測試失敗的,下面我們建立一個C# 的contract test的工程,然后測試消費(fèi)端和提供端是否匹配統(tǒng)一的契約。測試工程需要引用xUnit 和 PactNet的Nuget包,直接從Nuget server下載安裝就可以了,會把所有的依賴都添加進(jìn)來。新建BookingContractApiTesting 的class:private readonly ITestOutputHelper _output; public RetriveBookingApiContractTesting(ITestOutputHelper output) _output = output; Fact public void EnsureEventApiHonoursPactWithConsumer() const string serviceUri = http:/localhost:51502; var config = new PactVerifierConfig Outputters = new List new XUnitOutput(_output) , Verbose = false ; IPactVerifier pactVerifier = ne
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年電力市場分析與預(yù)測專業(yè)題庫
- 信息安全檢測與防護(hù)手段
- 深入探討人工智能的未來
- 2026福建泉州市石獅市鴻山鎮(zhèn)人民政府招聘編外人員4人備考題庫附答案詳解
- 2026福建三明市沙縣區(qū)緊缺急需學(xué)科教育人才引進(jìn)7人備考題庫及完整答案詳解一套
- 2026-2032年中國駐車踏板行業(yè)市場競爭現(xiàn)狀及發(fā)展趨勢研判報(bào)告
- 陶藝技法知識培訓(xùn)班課件
- 企業(yè)風(fēng)險(xiǎn)控制流程模板風(fēng)險(xiǎn)識別與應(yīng)對
- 河南省科學(xué)院碳基復(fù)合材料研究院科研輔助人員招聘備考題庫及答案詳解(易錯題)
- 技術(shù)項(xiàng)目立項(xiàng)評估分析工具
- 病蟲害防治操作規(guī)程編制
- 九年級上學(xué)期數(shù)學(xué)壓軸必考題型-反比例函數(shù)(含答案)
- 上海市旅館從業(yè)人員考試及答案解析
- 生日主題宴會設(shè)計(jì)方案
- 《基坑圍護(hù)結(jié)構(gòu)滲漏檢測技術(shù)標(biāo)準(zhǔn)》
- 防火防爆電氣安全知識培訓(xùn)課件
- IML IMR部技術(shù)標(biāo)準(zhǔn)手冊
- ?;钒踩嘤?xùn)
- 知識產(chǎn)權(quán)保護(hù)方案及維權(quán)材料填寫指南
- 《電機(jī)學(xué)》課件 5 第四篇 同步電機(jī)
- 云南少數(shù)民族介紹
評論
0/150
提交評論