131 lines
5.1 KiB
Plaintext
131 lines
5.1 KiB
Plaintext
[[getting-started-introducing-spring-cloud-contract]]
|
|
= Introducing Spring Cloud Contract
|
|
|
|
include::partial$_attributes.adoc[]
|
|
|
|
Spring Cloud Contract moves TDD to the level of software architecture.
|
|
It lets you perform consumer-driven and producer-driven contract testing.
|
|
|
|
[[getting-started-introducing-spring-cloud-contract-history]]
|
|
== History
|
|
|
|
Before becoming Spring Cloud Contract, this project was called https://github.com/Codearte/accurest[Accurest].
|
|
It was created by https://twitter.com/mgrzejszczak[Marcin Grzejszczak] and https://twitter.com/jkubrynski[Jakub Kubrynski]
|
|
from (https://github.com/Codearte[Codearte]).
|
|
|
|
The `0.1.0` release took place on 26 Jan 2015, and it became stable with `1.0.0` release on 29 Feb 2016.
|
|
|
|
[[getting-started-introducing-spring-cloud-contract-why]]
|
|
=== Why Do You Need It?
|
|
|
|
Assume that we have a system that consists of multiple microservices, as the following
|
|
image shows:
|
|
|
|
image::Deps.png[Microservices Architecture]
|
|
|
|
[[getting-started-introducing-spring-cloud-contract-testing-issues]]
|
|
=== Testing Issues
|
|
|
|
If we want to test the application in the top left corner of the image in the preceding
|
|
section to determine whether it can communicate with other services, we could do one of
|
|
two things:
|
|
|
|
- Deploy all microservices and perform end-to-end tests.
|
|
- Mock other microservices in unit and integration tests.
|
|
|
|
Both have their advantages but also a lot of disadvantages.
|
|
|
|
*Deploy all microservices and perform end-to-end tests*
|
|
|
|
Advantages:
|
|
|
|
- Simulates production.
|
|
- Tests real communication between services.
|
|
|
|
Disadvantages:
|
|
|
|
- To test one microservice, we have to deploy six microservices, a couple of databases,
|
|
and other items.
|
|
- The environment where the tests run is locked for a single suite of tests (nobody else
|
|
would be able to run the tests in the meantime).
|
|
- They take a long time to run.
|
|
- The feedback comes very late in the process.
|
|
- They are extremely hard to debug.
|
|
|
|
*Mock other microservices in unit and integration tests*
|
|
|
|
Advantages:
|
|
|
|
- They provide very fast feedback.
|
|
- They have no infrastructure requirements.
|
|
|
|
Disadvantages:
|
|
|
|
- The implementor of the service creates stubs that might have nothing to do with
|
|
reality.
|
|
- You can go to production with passing tests and failing production.
|
|
|
|
To solve the aforementioned issues, Spring Cloud Contract was created. The main idea is to
|
|
give you very fast feedback, without the need to set up the
|
|
whole world of microservices. If you work on stubs, then the only applications you need
|
|
are those that your application directly uses. The following image shows the relationship
|
|
of stubs to an application:
|
|
|
|
image::Stubs2.png[Stubbed Services]
|
|
|
|
Spring Cloud Contract gives you the certainty that the stubs that you use were
|
|
created by the service that you call. Also, if you can use them, it means that they
|
|
were tested against the producer's side. In short, you can trust those stubs.
|
|
|
|
[[getting-started-introducing-spring-cloud-contract-purposes]]
|
|
== Purposes
|
|
|
|
The main purposes of Spring Cloud Contract are:
|
|
|
|
- To ensure that HTTP and messaging stubs (used when developing the client) do exactly
|
|
what the actual server-side implementation does.
|
|
- To promote the ATDD (acceptance test-driven development) method, and the microservices architectural style.
|
|
- To provide a way to publish changes in contracts that are immediately visible on both sides.
|
|
- To generate boilerplate test code to be used on the server side.
|
|
|
|
By default, Spring Cloud Contract integrates with http://wiremock.org[Wiremock] as the HTTP server stub.
|
|
|
|
IMPORTANT: Spring Cloud Contract's purpose is NOT to start writing business
|
|
features in the contracts. Assume that we have a business use case of fraud check. If a
|
|
user can be a fraud for 100 different reasons, we would assume that you would create two
|
|
contracts, one for the positive case and one for the negative case. Contract tests are
|
|
used to test contracts between applications, not to simulate full behavior.
|
|
|
|
[[getting-started-what-is-a-contract]]
|
|
== What Is a Contract?
|
|
|
|
As consumers of services, we need to define what exactly we want to achieve. We need to
|
|
formulate our expectations. That is why we write contracts. In other words, a contract is
|
|
an agreement on how the API or message communication should look. Consider the following example:
|
|
|
|
Assume that you want to send a request that contains the ID of a client company and the
|
|
amount it wants to borrow from us. You also want to send it to the `/fraudcheck` URL by using
|
|
the `PUT` method. The following listing shows a contract to check whether a client should
|
|
be marked as a fraud in both Groovy and YAML:
|
|
|
|
[tabs]
|
|
======
|
|
groovy::
|
|
+
|
|
[source,groovy,indent=0,role="primary"]
|
|
----
|
|
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/fraud/shouldMarkClientAsFraud.groovy[]
|
|
----
|
|
======
|
|
////
|
|
|
|
////
|
|
[source,yaml,indent=0,role="secondary"]
|
|
.yaml
|
|
----
|
|
include::{samples_path}/standalone/dsl/http-server/src/test/resources/contracts/yml/fraud/shouldMarkClientAsFraud.yml[]
|
|
----
|
|
|
|
IMPORTANT: It is expected that contracts are coming from a **trusted source**. You should never download nor interact with contracts coming from untrusted locations.
|
|
|