Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

1,656 views

Published on

CDCs are “Asynchronous Integration Tests”.CDC stands for Consumer Driven Contract. We can now forget about bringing up all the microservices to test the integration between different microservices.This makes integration tests as simple as unit tests. This is a must-have test for all microservices.

Published in: Software
  • D0WNL0AD FULL ▶ ▶ ▶ ▶ http://1lite.top/xXGdu ◀ ◀ ◀ ◀
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Jeevan's revision guide has helped understand questions which I did not understand before in class. It has really helped me learn things the easy way. It's straightforward and shows you how to get a top grade in GCSE maths, in a step-by-step format...  http://t.cn/AirraVnG
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

  1. 1. Pact Tests (Consumer Driven Contracts)
  2. 2. 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!
  3. 3. 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”
  4. 4. Here comes the bigger question… Why didn't our tests catch this??
  5. 5. So how do you test? ● Mock the dependencies Subscription Service Mock CustomerInfo Service Request Response
  6. 6. 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! ”
  7. 7. Unit Tests ● Why do we still do it? • Fast • Easy to setup • No Flakiness! • Ensures functionality of a specific microservice
  8. 8. Integration Tests Subscription Service CustomerInfo Service Request Response
  9. 9. Integration Tests ● Slower ● Set up time (“Stack Setup!”) ● More flakiness ● More infrastructure! ● End up doing an E2E tests
  10. 10. Other types of Tests •End-to-End Tests •Manual Tests •Again, • Stack Setup! • Slower (E2E tests) • More flakiness • Not failing fast!
  11. 11. Solution? Is there a better way to identify these kind of issues?
  12. 12. 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.
  13. 13. Pact Tests? What are these? Subscription Service CustomerInfo Service Request Response Consumer Provider
  14. 14. 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
  15. 15. Is it just another Mock HTTP Server? Subscription Service CustomerInfo Service Request Response Consumer Provider
  16. 16. 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.
  17. 17. Pact Tests:Provider Side CustomerInfo Service Replay each HTTP Request Get real HTTP Response Provider Pact File Compares real and mock responses
  18. 18. Provider States • Get billing address of customer with id=777 Subscription Service CustomerInfo Service Request Response Consumer Provider Request Response ?
  19. 19. 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
  20. 20. Sharing Pact Files Filesystem Cloud Pact BrokerCI Build Artefact
  21. 21. 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
  22. 22. Sharing Pact Files - Pact Broker
  23. 23. Automating Pact Tests • When a new Pact is published, how does the Provider get notified? Manual Trigger Pact Broker Webhook Swagger Validator
  24. 24. Advantages •Eliminates Wrong Assumptions •Enables communication •Very less setup time! •No extra infrastructure •Fast in Execution •Fails Fast •No flakiness! •Easy to debug
  25. 25. DEMO Freshapps DevPortal Freshapps Activities Request Response Consumer Provider
  26. 26. Consumer Side : Setup Mock Server Pact.service_consumer 'DevPortal' do end
  27. 27. Consumer Side : Setup Mock Server Pact.service_consumer 'DevPortal' do has_pact_with "Freshapps Activities" do end end
  28. 28. 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
  29. 29. Consumer Side : Setup Expectations freshapps_activities.given(“all activities without role param")
  30. 30. 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'} )
  31. 31. 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" } )
  32. 32. Consumer Side : Make Request & Assert resp = FreshappsActivitiesClient.get_activities(path, query, header)
  33. 33. 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)
  34. 34. 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" } }
  35. 35. Provider Side : Make Request & Assert Pact.service_provider 'Freshapps Activities' do end
  36. 36. Provider Side : Make Request & Assert Pact.service_provider 'Freshapps Activities' do honours_pact_with 'DevPortal' do end end
  37. 37. 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
  38. 38. 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")
  39. 39. 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")
  40. 40. Provider Side : Pact Verify Failure
  41. 41. Provider Side : Pact Verify Success
  42. 42. 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.)
  43. 43. References ● To know about Consumer Driven Contract: https:// martinfowler.com/articles/consumerDrivenContracts.html ● https://www.thoughtworks.com/radar/techniques/ consumer-driven-contract-testing
  44. 44. And… What happened to Alice? Oh yea! She implemented “Pact Tests” and lived happily ever-after!!
  45. 45. Questions
  46. 46. Thank You!

×