spring-cloud-contract icon indicating copy to clipboard operation
spring-cloud-contract copied to clipboard

Spring Cloud Contract Generates Weak Tests

Open DhavalShewale opened this issue 2 years ago • 2 comments

Producer side test cases generated by Spring Cloud Contract have weak assertions which can also pass even while it is behaving incorrectly.

Sharing a sample contract to elaborate on my concern.

Contract

request:
  method: GET
  url: /staticData/getAnswers
response:
  status: 200
  body:
    - "value": "0"
      "displayText": "No"
    - "value": "1"
      "displayText": "Yes"
  headers:
    Content-Type: application/json

Generated Test

...
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).array().contains("['value']").isEqualTo("0");
assertThatJson(parsedJson).array().contains("['displayText']").isEqualTo("No");
assertThatJson(parsedJson).array().contains("['value']").isEqualTo("1");
assertThatJson(parsedJson).array().contains("['displayText']").isEqualTo("Yes");
...

The above generated test would also pass if the producer returned any of the below incorrect outputs.

[
  {
    "value": "0",
    "displayText": "Yes"
  },
  {
    "value": "1",
    "displayText": "No"
  }
]
[
  {
    "value": "0",
    "displayText": "No"
  },
  {
    "value": "1",
    "displayText": "Yes"
  }, 
  {
    "value": "-1",
    "displayText": "NA"
  }, 
]

Here I would like to highlight two concerns:

  • The test can be false successful by cross comparing the data as highlighted in example 1
  • The test can be false successful even when additional unexpected elements are returned

Also, I tried using spring.cloud.contract.verifier.assert.size and assertJsonSize property but they had no effect on the generated test classes so it seems to be fully ignored.

Generated test classes should look more like the below code to avoid such false success scenarios

DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).elementWithIndex(0).field("['value']").isEqualTo(0);
assertThatJson(parsedJson).elementWithIndex(0).field("['displayText']").isEqualTo("No");
assertThatJson(parsedJson).elementWithIndex(1).field("['value']").isEqualTo(1);
assertThatJson(parsedJson).elementWithIndex(1).field("[displayText']").isEqualTo("Yes");
assertThatJson(parsedJson).array().hasSize(2);

This code was tested on Java 11 with Spring Boot Version 2.7.13 and Spring Cloud Contract Version 3.1.8

DhavalShewale avatar Aug 07 '23 18:08 DhavalShewale

@marcingrzejszczak: Tks for acknowledging the request and tagging it as an enhancement.

I wanted to enquire whether this can be taken up in the near future or this is currently at the bottom of the stack pending prioritization.

DhavalShewale avatar Aug 18 '23 16:08 DhavalShewale