【软件测试】Java消费者驱动的合同测试

Chinese, Simplified

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
:test

BUILD 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_dummyProvider

Verifying 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)
:pactVerify

BUILD SUCCESSFUL

Total time: 9.936 secs

 

完整的例子
https://github.com/the-creative-tester/consumer-driven-contract-testing-example

 

SEO Title
Java Consumer Driven Contract Testing