【软件测试】Java消费者驱动的合同测试
Java中的Pact-JVM和Gradle
介绍
在这篇文章中,我们将在Gradle Spring Boot虚拟提供程序(RESTful Web Service)和Gradle虚拟使用者之间编写一个Consumer Driven Contract Test。
我们将使用Pact-JVM,它将为消费者项目提供模拟服务以生成Pact,并为提供者项目验证能力以验证Pact。
安装
Gradle
Gradle Wrapper允许任何人在不必安装Gradle的情况下处理您的项目。它确保构建的正确版本的Gradle作为此项目存储库的一部分提供。首先克隆包含虚拟提供者和虚拟消费者的样本库:
bash-3.2$ git clone https://github.com/the-creative-tester/consumer-driven-contract-testing-example.git Cloning into 'consumer-driven-contract-testing-example'...
remote: Counting objects: 47, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 47 (delta 2), reused 42 (delta 1), pack-reused 0 Unpacking objects: 100% (47/47), done.
Checking connectivity... done.
提供者设置
导航到提供程序目录,您将在其中看到通过本指南使用Sprint Boot和Gradle构建的示例RESTful Web Service。尝试使用以下命令运行该服务:
bash-3.2$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar
.. 2016-07-03 14:49:59.367 INFO 32114 --- [ main] hello.HelloWorldConfiguration : Started HelloWorldConfiguration in 6.782 seconds (JVM running for 7.452)
您现在应该能够通过导航到http:// localhost:8080 / hello-world或使用curl来达到服务(观察每次向服务发出请求时id增加):
bash-3.2$ curl http://localhost:8080/hello-world {"id":2,"content":"Hello World!"}
消费者设置
从消费者的角度来看,总是要生成契约。这一代可以分为三个部分。
第1部分:契约规则
在这一部分中,我们定义了一个模拟服务器的主机和端口来表示提供者:
@Rule
public PactRule rule = new PactRule(Configuration.MOCK_HOST, Configuration.MOCK_HOST_PORT, this);
private DslPart helloWorldResults;
第2部分:契约片段
在这一部分中,我们构建了一个Pact Fragment,它定义了一个提供者的预期契约:
@Pact(state = "HELLO WORLD", provider = Configuration.DUMMY_PROVIDER, consumer = Configuration.DUMMY_CONSUMER)
public PactFragment createFragment(ConsumerPactBuilder.PactDslWithProvider.PactDslWithState builder)
{
helloWorldResults = new PactDslJsonBody()
.id()
.stringType("content")
.asBody();
return builder
.uponReceiving("get hello world response")
.path("/hello-world")
.method("GET")
.willRespondWith()
.status(200)
.headers(Configuration.getHeaders())
.body(helloWorldResults)
.toFragment();
}
第3部分:契约验证
在这一部分中,我们确保第2部分中构造的片段与模拟服务器的响应匹配:
@Test
@PactVerification("HELLO WORLD")
public void shouldGetHelloWorld() throws IOException
{
DummyConsumer restClient = new DummyConsumer(Configuration.SERVICE_URL);
assertEquals(helloWorldResults.toString(), restClient.getHelloWorld());
}
尝试使用消费者目录中的Gradle生成Pact:
bash-3.2$ ./gradlew test
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:testBUILD SUCCESSFUL
Total time: 10.67 secs
然后将生成Pact并将其存储在pacts目录中,但它看起来像这样:
{
"provider" : {
"name" : "dummy-provider"
},
"consumer" : {
"name" : "dummy-consumer"
},
"interactions" : [ {
"providerState" : "HELLO WORLD",
"description" : "get hello world response",
"request" : {
"method" : "GET",
"path" : "/hello-world"
},
"response" : {
"status" : 200,
"headers" : {
"Content-Type" : "application/json;charset=UTF-8"
},
"body" : {
"id" : 5677679801,
"content" : "dugNvVPasiFRnzqpPNuq"
},
"responseMatchingRules" : {
"$.body.id" : {
"match" : "type"
},
"$.body.content" : {
"match" : "type"
}
}
}
} ],
"metadata" : {
"pact-specification" : {
"version" : "2.0.0"
},
"pact-jvm" : {
"version" : "2.1.12"
}
}
}
提供者
现在,Pact已由Consumer生成,并假设Provider(RESTful Web Service)正在运行。您可以从提供程序目录运行以下命令,以确保提供程序满足Consumer的所有期望:
bash-3.2$ ./gradlew pactVerify
:pactVerify_dummyProviderVerifying a pact between dummy-consumer and dummyProvider
[Using file /Users/jasonthye/Dev/pact-example-gradle/pacts/dummy-consumer-dummy-provider.json]
Given HELLO WORLD
WARNING: State Change ignored as there is no stateChange URL
get hello world response
returns a response which
has status code 200 (OK)
includes headers
"Content-Type" with value "application/json;charset=UTF-8" (OK)
has a matching body (OK)
:pactVerifyBUILD SUCCESSFUL
Total time: 9.936 secs
完整的例子
https://github.com/the-creative-tester/consumer-driven-contract-testing-example
- 35 次浏览