47
Pact Tests (Consumer Driven Contracts)

CDC Tests - Integration Tests cant be made simpler than this!

Embed Size (px)

Citation preview

Page 1: CDC Tests - Integration Tests cant be made simpler than this!

Pact Tests (Consumer Driven Contracts)

Page 2: CDC Tests - Integration Tests cant be made simpler than this!

Based on a true (truly imaginary?) story!

Alice

• our main character in the story

• Senior Dev in FreshMock.com

• Owns a “Subscription Service”

• Friday the 13th!

Page 3: CDC Tests - Integration Tests cant be made simpler than this!

What happened on Friday the 13th?

● “CustomerInfo Service”’s change

● Updates a property in the response object

● Changes “customer” (which returns a list of customers) to

“customers” (Grammatically correct though! :( )

● BUT this one letter change BROKE the “Subscription Service”

Page 4: CDC Tests - Integration Tests cant be made simpler than this!

Here comes the bigger question…

Why didn't our tests catch this??

Page 5: CDC Tests - Integration Tests cant be made simpler than this!

So how do you test?

● Mock the dependencies

Subscription Service Mock CustomerInfo Service

Request

Response

Page 6: CDC Tests - Integration Tests cant be made simpler than this!

Unit Tests

● Similarly the “CustomerInfo Service”, has a mock client for

“Subscription Service”

● It DID fail!

● But then “I updated my test because I know this is an expected

failure! ”

Page 7: CDC Tests - Integration Tests cant be made simpler than this!

Unit Tests

● Why do we still do it?

• Fast

• Easy to setup

• No Flakiness!

• Ensures functionality of a specific microservice

Page 8: CDC Tests - Integration Tests cant be made simpler than this!

Integration Tests

Subscription Service CustomerInfo Service

Request

Response

Page 9: CDC Tests - Integration Tests cant be made simpler than this!

Integration Tests

● Slower

● Set up time (“Stack Setup!”)

● More flakiness

● More infrastructure!

● End up doing an E2E tests

Page 10: CDC Tests - Integration Tests cant be made simpler than this!

Other types of Tests•End-to-End Tests

•Manual Tests

•Again,

• Stack Setup!

• Slower (E2E tests)

• More flakiness

• Not failing fast!

Page 11: CDC Tests - Integration Tests cant be made simpler than this!

Solution?

Is there a better way to identify

these kind of issues?

Page 12: CDC Tests - Integration Tests cant be made simpler than this!
Page 13: CDC Tests - Integration Tests cant be made simpler than this!

Pact Tests

• Also called “Contract Tests”

• Consumer Driven Contract Tests (CDC Tests)

• Tool Used: Pact • A Contract is a collection of agreements between a client (Consumer)

and an API (Provider) that describes the interactions that can take

place between them.

Page 14: CDC Tests - Integration Tests cant be made simpler than this!

Pact Tests? What are these?

Subscription Service CustomerInfo Service

Request

Response

Consumer Provider

Page 15: CDC Tests - Integration Tests cant be made simpler than this!

Sends response

for assertions

Pact Tests: Consumer Side

Tests

Set Expectations

Pact Mock Provider

Tests invoke code

Source Code

Sends HTTP

Requests

Sends expected response

Page 16: CDC Tests - Integration Tests cant be made simpler than this!

Is it just another Mock HTTP Server?

Subscription Service CustomerInfo Service

Request

Response

Consumer Provider

Page 17: CDC Tests - Integration Tests cant be made simpler than this!

The Pact File

• Every HTTP Request and Response is

captured

• Standard way of representing

interactions - JSON file

• This is shared with the Provider.

• Explains everything that a consumer

expects from the Provider - the

endpoints, query params, header and

the response objects.

Page 18: CDC Tests - Integration Tests cant be made simpler than this!

Pact Tests:Provider Side

CustomerInfo Service

Replay each HTTP Request

Get real HTTP Response

ProviderPact File Compares real and

mock responses

Page 19: CDC Tests - Integration Tests cant be made simpler than this!

Provider States

• Get billing address of customer

with id=777

Subscription Service CustomerInfo Service

Request

Response

Consumer Provider

Request

Response

?

Page 20: CDC Tests - Integration Tests cant be made simpler than this!

state: cust_id=777 @ DB

Provider States

• Get billing address of customer

with id=777

Subscription Service CustomerInfo Service

Request

Response

Consumer Provider

Request

Response

state: cust_id=777 @ DB

state: cust_id=777 @ DB

Page 21: CDC Tests - Integration Tests cant be made simpler than this!

Sharing Pact Files

Filesystem Cloud Pact BrokerCI Build Artefact

Page 22: CDC Tests - Integration Tests cant be made simpler than this!

Sharing Pact Files - Pact Broker

• Pact Broker - a repo for storing pacts

• Auto-generated documentation

• The ability to tag a Pact (i.e. “prod") -

versioning pacts

• Network Graph

Page 23: CDC Tests - Integration Tests cant be made simpler than this!

Sharing Pact Files - Pact Broker

Page 24: CDC Tests - Integration Tests cant be made simpler than this!

Automating Pact Tests

• When a new Pact is published, how does the Provider get notified?

Manual Trigger Pact Broker

Webhook

Swagger Validator

Page 25: CDC Tests - Integration Tests cant be made simpler than this!

Advantages

•Eliminates Wrong Assumptions

•Enables communication

•Very less setup time!

•No extra infrastructure

•Fast in Execution

•Fails Fast

•No flakiness!

•Easy to debug

Page 26: CDC Tests - Integration Tests cant be made simpler than this!

DEMO

Freshapps DevPortal Freshapps Activities

Request

Response

Consumer Provider

Page 27: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Mock Server

Pact.service_consumer 'DevPortal' do

end

Page 28: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Mock Server

Pact.service_consumer 'DevPortal' do has_pact_with "Freshapps Activities" do

end end

Page 29: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Mock Server

Pact.service_consumer 'DevPortal' do has_pact_with "Freshapps Activities" do mock_service :freshapps_activities do port 3005 end end end

Page 30: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Expectations

freshapps_activities.given(“all activities without role param")

Page 31: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Expectations

freshapps_activities.given(“all activities without role param") .upon_receiving("a request for all activities") .with( method: :get, path: '/all/activities.json', query: { page: '1', account_id: '1' }, headers: {'Content-Type' => 'application/json', 'Accept' => 'application/json'} )

Page 32: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Setup Expectations

freshapps_activities.given(“all activities without role param") .upon_receiving("a request for all activities") .with( method: :get, path: '/all/activities.json', query: { page: '1', account_id: '1' }, headers: {'Content-Type' => 'application/json', 'Accept' => 'application/json'} ) .will_respond_with( status: 422, headers: { 'Content-Type' => 'application/json; charset=utf-8' }, body: { "error_msg" => "Required parameter missing" } )

Page 33: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Make Request & Assert

resp = FreshappsActivitiesClient.get_activities(path, query, header)

Page 34: CDC Tests - Integration Tests cant be made simpler than this!

Consumer Side : Make Request & Assert

resp = FreshappsActivitiesClient.get_activities(path, query, header) expected_response = { "error_msg" => "Required parameter missing" } expect(resp.parsed_response.inspect).to eq(expected_response.inspect)

Page 35: CDC Tests - Integration Tests cant be made simpler than this!

Generated Pact File { "consumer": { "name": "DevPortal" }, "provider": { "name": "Freshapps Activities" }, "interactions": [ { "description": "a request for all activities", "provider_state": "all activities without role param", "request": { "method": "get", "path": "/all/activities.json", "query": "page=1&account_id=1", "headers": { "Content-Type": "application/json", "Accept": "application/json" } }, "response": { "status": 422, "headers": { "Content-Type": "application/json; charset=utf-8" }, "body": { "error_msg": "Required parameter missing" } } } ], "metadata": { "pactSpecificationVersion": "1.0.0" } }

Page 36: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Make Request & Assert

Pact.service_provider 'Freshapps Activities' do

end

Page 37: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Make Request & Assert

Pact.service_provider 'Freshapps Activities' do honours_pact_with 'DevPortal' do end end

Page 38: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Make Request & Assert

Pact.service_provider 'Freshapps Activities' do honours_pact_with 'DevPortal' do pact_uri "../freshapps_devportal/spec/pacts/devportal-freshapps_activities.json" end end end

Page 39: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Setup Test Data

Pact.provider_states_for "DevPortal" do provider_state "all activities without role param" do

end end

Remember: Consumer Assumed:

freshapps_activities.given(“all activities without role

param")

Page 40: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Setup Test Data

Pact.provider_states_for "DevPortal" do provider_state "all activities without role param" do set_up do factory :activity do account_id 1 user_id 1 extension_id 2 version_id 2 activity_type 'Extension' visibility 1 activity { 'extension_id' => '2', 'name' => 'Sample Extension’} end end end end

Remember: Consumer Assumed:

freshapps_activities.given(“all activities without role

param")

Page 41: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Pact Verify Failure

Page 42: CDC Tests - Integration Tests cant be made simpler than this!

Provider Side : Pact Verify Success

Page 43: CDC Tests - Integration Tests cant be made simpler than this!

pact.io

• Working examples and documentations available at pact.io

• Supports: Ruby, Java, .NET

• Beta: JS,Python, Swift, Go

• https://groups.google.com/forum/#!forum/pact-support

• https://gitter.im/realestate-com-au/pact

• Other Similar Tools:

• Pacto (by Thoughtworks - but not maintained though.)

Page 44: CDC Tests - Integration Tests cant be made simpler than this!

References

● To know about Consumer Driven Contract: https://

martinfowler.com/articles/consumerDrivenContracts.html

● https://www.thoughtworks.com/radar/techniques/

consumer-driven-contract-testing

Page 45: CDC Tests - Integration Tests cant be made simpler than this!

And… What happened to Alice?

Oh yea! She implemented “Pact Tests”

and

lived happily ever-after!!

Page 46: CDC Tests - Integration Tests cant be made simpler than this!

Questions

Page 47: CDC Tests - Integration Tests cant be made simpler than this!

Thank You!