Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Consumer Driven Contract Testing workshop

Yoan
August 14, 2019

Consumer Driven Contract Testing workshop

Created with Wilfried Vandenberghe.

Yoan

August 14, 2019
Tweet

More Decks by Yoan

Other Decks in Technology

Transcript

  1. Consumer Driven Contracts Testing
    “Design your api differently”

    View Slide

  2. In a microservices world,
    how do you deal with testing?

    View Slide

  3. How to confirm all services are working together?

    View Slide

  4. How to write a test for it ?
    Client Api
    Request
    Response

    View Slide

  5. Mocking !!!
    Client Api
    Request
    Response
    Mock or Stub

    View Slide

  6. Problems
    •What happens if there is a change in the real producer ?
    •The owner of the mock is the consumer
    •Not trustworthy

    View Slide

  7. Client
    Mock or Stub
    Api
    Test Real world
    Mocking !!!
    Request
    Response
    The mock has nothing to do with
    the real API
    Client
    Real Service
    Api
    Request
    Response

    View Slide

  8. How can we be sure that the mocks are
    valid?

    View Slide

  9. END TO END TESTS
    Client REAL api
    Request
    Response

    View Slide

  10. Problems
    •Slow
    •All services need to be up before running the tests
    •Require a clean/dedicated integration environment

    View Slide

  11. But it is trustworthy

    View Slide

  12. Any alternative ?
    Could we test apis in a better way ?

    View Slide

  13. If no cooperation

    View Slide

  14. #Questions
    It’s the consumer that uses the API.
    Would it be possible that :
    ● consumer takes part in the creation of the API of the
    producer ?
    ● API changes be driven by consumers ?

    View Slide

  15. “An integration test is a test between an API provider and an API consumer that
    asserts that the provider returns expected responses for a set of pre-defined
    requests by the consumer.
    The set of pre-defined requests and
    expected responses is called a contract.”

    View Slide

  16. Consumer Driven
    Contracts

    View Slide

  17. Glossary
    •Producer
    Service that exposes an API.
    •Consumer
    Service that consumes the API of the producer.
    •Contract
    Agreement between producer and consumer on how the API will look like.
    •Consumer Driven Contracts
    Approach where the consumer drives the changes of the API of the producer.

    View Slide

  18. View Slide

  19. As a developer
    I want to confirm that the consumer (client) and the
    provider (service) can understand each others
    So that I can check they are compatibles

    View Slide

  20. How to ?
    Define API contract on the consumer side.
    The contract must be enforced on the service provider.

    View Slide

  21. Contract test

    View Slide

  22. View Slide

  23. Tools ?

    View Slide

  24. https://docs.pact.io/

    View Slide

  25. View Slide

  26. 1) Start With Consumer

    View Slide

  27. 1) Start With Consumer
    • Write Test(S)
    • Define interactions / Expectations
    • In your favorite language

    View Slide

  28. 1) Start With Consumer
    • Run Tests
    • From Expectations TO Contract
    • Json File

    View Slide

  29. 2) Contract Driven Development

    View Slide

  30. 2) Contract Driven Development
    • Design Your API From The Contract
    • Write A RED Test

    View Slide

  31. 2) Contract Driven Development
    • Make You Test Pass / GREEN

    View Slide

  32. • Git ?
    • Near from the Provider sources ?
    • Near from the Consumer sources ?
    • Any better option ?
    Where Could We Store Our CONTRACTS ?

    View Slide

  33. Pact Broker
    ● A RESTful API for
    publishing and retrieving pacts.
    ● An embedded API
    browser for navigating the API.
    ● Displays provider
    verification results so you know if you can deploy safely.

    Auto-generated documentation for each pact.
    ● Provides a
    "matrix" of compatible consumer and provider versions, so you know which versions can be safely deployed together.
    ● Dynamically generated network diagrams so you can
    visualise your microservice network.
    ● Provides badges to display pact verification statuses in your READMEs.
    ● Enables an application version to be tagged (ie. "prod", "feat/customer-preferences") to allow repository-like workflows.
    ● Provides
    webhooks to trigger actions when pacts change eg. run provider build, notify a Slack channel.
    ● View diffs between Pact versions so you can tell what expectations have changed.
    ● Docker Pact Broker
    ● A
    CLI for encorporating the Pact workflow into your continuous integration process.
    https://github.com/pact-foundation/pact_broker

    View Slide

  34. A RESTful API for
    publishing and retrieving pacts.
    An embedded API
    browser for navigating the API. Displays provider
    verification results so you know if you can deploy safely.

    View Slide

  35. Auto-generated documentation for each pact.
    Provides a
    "matrix" of compatible consumer and
    provider versions,

    View Slide

  36. Dynamically generated network diagrams so you can
    visualise your microservice network.
    sheriff hopper

    View Slide

  37. A
    CLI for encorporating the Pact workflow into your continuous integration process. Docker Pact Broker

    View Slide

  38. Provides
    webhooks to trigger actions when pacts change eg. run provider build, notify a Slack channel.
    https://github.com/pact-foundation/pact_broker/blob/master/lib/pact_broker/doc/views/webhooks.markdown

    View Slide

  39. View Slide

  40. Strengths
    Opportunities Threats
    Weaknesses
    ● Cross-languages
    ● Easy integration with a pact broker
    ● Specification / standardization
    ● 2 versions of the Specification
    ○ 3.0 for JVM
    ○ 2.0 for others
    ● Api quality depends on the language
    ● Where to store the Contracts ? (if no broker)
    ● Yet another format (Not Open Api)
    ● Start easily A CDC approach
    ○ Only a few Jar to reference
    ● Design First approach Wanted ?
    ● Contract + Integration Tests ?
    https://github.com/agilepartner/pact-sandbox

    View Slide

  41. Spring Cloud Contract Doc
    Spring Cloud Contract is an umbrella project holding solutions that help users in successfully implementing
    the Consumer Driven Contracts approach. Currently Spring Cloud Contract consists of the Spring Cloud
    Contract Verifier project.
    Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of
    JVM-based applications. It is shipped with Contract Definition Language (DSL) written in Groovy or YAML.
    Spring Cloud Contract Verifier moves TDD to the level of software architecture.
    Contract definitions are used to produce following resources:
    ● by default JSON stub definitions to be used by WireMock (HTTP Server Stub) when doing
    integration testing on the client code (client tests). Test code must still be written by hand, test
    data is produced by Spring Cloud Contract Verifier.
    ● Messaging routes if you’re using one. We’re integrating with Spring Integration, Spring Cloud
    Stream and Apache Camel. You can however set your own integrations if you want to.
    ● Acceptance tests (by default in JUnit or Spock) used to verify if server-side implementation of the
    API is compliant with the contract (server tests). Full test is generated by Spring Cloud Contract
    Verifier.

    View Slide

  42. 1) Define The Contract

    View Slide

  43. 1) Define The Contract
    • Write contract in Groovy or YML
    • Define Expectations
    org.springframework.cloud.contract.spec.Contract.make {
    description("""
    Donuts API
    """)
    label("Get all donuts")
    request {
    method GET()
    url '/donuts'
    headers {
    contentType(applicationJson())
    }
    }
    response {
    status OK()
    body(
    sugar: $(regex('[0-9]+')) ,
    flour: $(regex('[0-9]+')) ,
    butter: $(regex('[0-9]+'))
    )
    headers {
    contentType(applicationJson())
    }
    }
    }

    View Slide

  44. 2) Contract Driven Development

    View Slide

  45. 2) Contract Driven Development
    • Design Your API From The Contract
    • Write A RED Test
    public abstract class ContractVerifierBase {
    @Before
    public void setup() {
    RestAssuredMockMvc.standaloneSetup(new DonutsController());
    }
    }
    org.springframework.cloud.contract.spec.Contract.ma
    ke {
    description("""
    Donuts API
    """)
    label("Get all donuts")
    request {
    method GET()
    url '/donuts'
    headers {
    contentType(applicationJson())
    }
    }
    response {
    status OK()
    body(
    sugar: $(regex('[0-9]+')) ,
    flour: $(regex('[0-9]+')) ,
    butter: $(regex('[0-9]+'))
    )
    headers {
    contentType(applicationJson())
    }
    }
    }

    View Slide

  46. 2) Contract Driven Development
    • Make You Test Pass / GREEN
    @RestController
    public class DonutsController {
    @GetMapping(value = "/donuts", produces = "application/json")
    public ResponseEntity getDonuts() {
    return ResponseEntity.ok(Arrays.asList(new Donut(120, 150, 140)));
    }

    View Slide

  47. 3) Generate a stub from contract
    • TODO Make You Test Pass / GREEN
    @RestController
    public class DonutsController {
    @GetMapping(value = "/donuts", produces = "application/json")
    public ResponseEntity getDonuts() {
    return ResponseEntity.ok(Arrays.asList(new Donut(120, 150, 140)));
    }

    View Slide

  48. Strengths
    Opportunities Threats
    Weaknesses
    ● Tests generated by the framework
    ● Stub generated
    ● Contract DSL based
    ● Not cross-languages
    ● Dependency on Spring Cloud
    ● Where to store the Contracts ? centralized jar ?
    ● Yet another format. Open API is not directly
    supported
    ● No dependency visualization
    ● No central repository for contract
    ● Start easily A CDC approach
    ○ Only a few Jar to reference
    ● Design First approach Wanted ?
    ● Contract + Integration Tests ?
    https://github.com/wilvdb/contracts-lab

    View Slide

  49. • Git or jar ?
    • Near from the Provider sources ?
    • Near from the Consumer sources ?
    • Any better option ?
    Where Could We Store Our CONTRACTS ?

    View Slide

  50. View Slide

  51. #Workshop
    ● There is no more Donuts at Springfiled, and Homer
    is going to be crazy if he cannot get any donuts for
    breakfast
    ● Your mission : restart the donuts factory
    ● https://github.com/wilvdb/contracts-lab
    ○ Module docker : docker-compose up
    ○ Module simpson-client-pact : mvn install → Load
    contract on pact broker
    ○ Module donuts-factory-pact : complete
    DonutsController to validate the contract

    View Slide

  52. Apicurio Doc
    Apicurio Studio, maintained by the Red Hat Developer Program, is a tool for designing APIs that follows the specification
    without requiring the developer(s) to be intimately familiar with it. It provides a GUI for defining all aspects of the API.
    Ultimately, Apicurio outputs both human and machine readable documentation which complies with the latest version of the
    OpenAPI specification. This walkthrough covers the process of designing an API with Apicurio from start to finish, and
    evaluates the possibility of using Apicurio in production.
    Features:
    ● Support of OpenApi and Swagger
    ● Project code generation (limited support to JAX-RS for the moment
    ● Storage of contract on GIT
    ● Microcks integration (mocking and integration testing tool)

    View Slide

  53. Microcks Doc
    Microcks helps providers of API and micro-services to rapidly deliver :
    ● A comprehensible vision of their API, exposing sample requests and responses as well as base
    functional rules (cases when API responds A or B or raises exceptions)
    ● A set of testing environments to allow API consumers or System Under Tests to use API even if
    implementation is not finished!
    ● Contract testing plans of their API, allowing them to run, record and compare contract tests run
    against different environments.

    View Slide

  54. Swagger Codegen
    Swagger Codegen can simplify your build process by generating server stubs and client SDKs for any
    API, defined with the OpenAPI (formerly known as Swagger) specification, so your team can focus better
    on your API’s implementation and adoption.

    io.swagger.codegen.v3
    swagger-codegen-maven-plugin


    generate


    ${project.basedir}/src/main/resources/api.yml
    spring
    ${default.package}.controller
    ${default.package}.model.dto
    ${default.package}.handler
    false
    false

    true
    true




    @Api(value = "pets", description = "the pets API")
    public interface PetsApi {
    @ApiOperation(value = "", nickname = "addPet", notes = "Creates a new pet in the
    store. Duplicates are allowed", response = Pet.class, tags={ })
    @ApiResponses(value = {
    @ApiResponse(code = 200, message = "pet response", response = Pet.class),
    @ApiResponse(code = 200, message = "unexpected error", response = Error.class) })
    @RequestMapping(value = "/pets",
    produces = { "application/json" },
    consumes = { "application/json" },
    method = RequestMethod.POST)
    default ResponseEntity addPet(@ApiParam(value = "Pet to add to the store"
    ,required=true ) @Valid @RequestBody NewPet body) {...}

    View Slide

  55. NEXT STEPS ?

    View Slide

  56. #resources
    7 reasons for consumer driven contracts
    Spring Cloud Contract meet Pact
    Consumer driven contract testing using pact

    View Slide