============ Introduction ============ Contract testing is used to test that two systems have a shared understanding of expectations. For example when a web app sends a GET request to a service, the web app has an expectation on how the service will respond. Contract testing will see the interaction of the two systems, create a contract that both systems must adhere to. If ever one part breaks the contract it will be flagged and reviewed by both systems before we can deploy to prod. Say we have a user API, where a web app does a GET with a user id and the API gives you the details on that user. If we do a simple integration test then the web app would do a GET to the API and assert that the id we requested has the info we want. The main difference in contract testing is that the web app and the user API do not need to interact directly. They interact via a shared contract. This contract is created were the web app records the actual request and response and upload it to a shared broker which both parties will use. Why use it? ----------- Combines the high confidence that an API integration test provides with the speed and low maintenance and cheaper cost of running a unit test. Consumer side ------------- Most of the test writing will happen here because we will define the contract. The consumer defines the interaction with the mock provider. - Interaction: the request and response that will be registered to the mock provider. - Request: describes what the consumer will send to the provider. - Response: describes what the provider needs to return When a request gets to the mock provider it will check if the request is registered as an interaction. If so the mock provider returns the expected response and the consumer confirms that the expected response is understood. Provider side ------------- 1. Provider downloads the contract generated by the consumer from the broker 2. Using the contract testing tool, the expected request is replayed, and the provider send the actual response to the expected request. 3. The contract testing tool compares the responses, if the results match the verification is successful My Summary ---------- We have a consumer and a provider. The consumer will write a contract on what he expects from the provider. Meaning what requests will return what things. It will send this contract to a broker. The provider will see the contract and validate it with its responses. If it passes everything it will be approved and added to the broker. Now, the consumer make some changes to their code. When the test suit is run it will verify that responses against a mock provider, which is created based on the contract. The provider wont be bothered again. Unless the contract is broken and it has to verify it again from their part =================== Other testing types =================== Unit testing ------------ Individual units are tested to determine that a software component does what it is supposed to do. They have a fast execution, due to them running in an isolated environment. Do not require integrated environments. Integration testing ------------------- Validate the integrations points between components or services. End to End testing ------------------ Mimic user interactions and replicate real-world scenarios Contract testing does not replace Integration Testing. It does not verify: - environment problems caused by config problems - network problems - data integrity relating to how the data is stored Benefits of contract testing ---------------------------- - cost savings benefits: - quicker execution time against integration or e2e testing. - although, it takes more time to setup due to it having a higher complexity - developers can execute them from their system - quality benefits - catches misunderstandings between systems, early in the process. - teams benefits - enforces various teams to communicate with each other. Mitigates the risk of misinterpretations. - the contracts are clear and unambiguous. They are usually written in plain English Introduce contract saving to others ----------------------------------- * start with why why -> how -> what (golden circle by simon sinek) - how contract testing complements existing testing strategies. - document process - find people to join you - start small Challenges of contract testing ------------------------------ - takes time - the initial setup is longer. - but they are easier to maintain when they are in place. - mind shift to more collaborative process - lack of buy-in - more technical than other testing activities How to introduce it ------------------- - research what tools to use - identify your consumers and providers - define the contract - the consumer defines the contract, which specifies expectations from the provider. - only check format and structure of response. Do not cover business logic. - write a basic consumer and provider test - add contract testing to your ci/cd ================== Technical overview ================== Before writing contract test code you must start a conversation with the key stakeholders regarding where to store the contracts. There are two approaches to contract testing: - consumer-driven contract testing (traditional approach) - provider-driven contract testing Usual approach for integration testing. The API service team implements the tests during the dev process. Once the tests are passed the api is deployed to an integration env so other teams can check if their integration will work successfully. The short-comings with this approach are: - env setup and maintenance problems - bad seed data - env not reliable One option is to containerize the integration environment, and spin it up on-demand using something like Docker. Other option is to set up a full integration environment, this would be closer to prod, but it is also harder to maintain Contract testing reduces the effort required compared with the first option and simulates the integration environment, but also gives the confidence for the second option. Consumer -------- A consumer is a user of a product or service. Anything that makes a request to another service whether to retrieve data, post and update, or consume an event. Usually this is the one that drives the contract, in a front end app, the user do not care how the data is formatted from the server. The server needs to comply with the reqs of the client. This is why the consumer creates the contract. Provider -------- Makes a service available to someone who needs it. A service returning the relevant data. Contract -------- A contract is a JSON object that has consumer and provider interactions, outlining a requests details and expected response data. It is different with a _schema_. An _schema_ provides the outline, facilitates describing the json's structure, rules and constrains. But the difference is that a schema does not tell how consumers use the data.