diff --git a/_includes/setup_command_line.md b/_includes/setup_command_line.md index de4d43c19..c66711558 100644 --- a/_includes/setup_command_line.md +++ b/_includes/setup_command_line.md @@ -22,6 +22,22 @@ Run specmatic by ``` bash $ npx specmatic ``` +{% endtab %} + +{% tab install docker %} + +Docker Pull Command for specmatic docker image + +``` bash +> docker pull znsio/specmatic +``` + +Run specmatic by + +``` bash +docker run znsio/specmatic +``` + {% endtab %} {% endtabs %} diff --git a/documentation/backward_compatibility.md b/documentation/backward_compatibility.md index 1580f39a8..d169734f3 100644 --- a/documentation/backward_compatibility.md +++ b/documentation/backward_compatibility.md @@ -76,7 +76,7 @@ This contract contains an API for fetching the details of a product. Let's add a new api to create a product record: ```yaml -# filename api_products_v1-2.yaml +# filename api_products_v2.yaml openapi: 3.0.0 info: title: Sample Product API @@ -150,13 +150,25 @@ The newer contract is backward compatible with the older, as existing consumers Run the specmatic compare command to confirm this, and see the result: +{% tabs compare %} +{% tab compare java %} +```bash +java -jar specmatic.jar compare api_products_v1.yaml api_products_v2.yaml +``` +{% endtab %} +{% tab compare docker %} ```bash -> java -jar specmatic.jar compare api_products_v1.yaml api_products_v1-2.yaml +docker run -v "/local-directory:/specs" znsio/specmatic compare "/specs/api_products_v1.yaml" "/specs/api_products_v2.yaml" +``` +{% endtab %} +{% endtabs %} +You should now see an output as shown below. +```bash The newer contract is backward compatible ``` -Let's change the original contract of square to return "sku" as a numeric value instead of string in the response: +Let's change the original contract of square to return `sku` as a num `integer` instead of `string` in the response: ```yaml # filename api_products_v2.yaml @@ -194,17 +206,28 @@ paths: properties: name: type: string - sku: + sku: #this has changed from string to integer type: integer ``` -Note that the file name of the above file is api_products_v2.yaml. - Now try it again: +{% tabs compare2 %} +{% tab compare2 java %} ```bash -> java -jar specmatic.jar compare api_math_v1.yaml api_math_v2.yaml +java -jar specmatic.jar compare api_products_v1.yaml api_products_v2.yaml +``` +{% endtab %} +{% tab compare2 docker %} +```bash +docker run -v "/local-directory:/specs" znsio/specmatic compare "/specs/api_products_v1.yaml" "/specs/api_products_v2.yaml" +``` +{% endtab %} +{% endtabs %} +Specmatic will show you an error message, saying that the change is not backward compatible. The reason for this is that existing consumers are expecting a string "sku", but will get an "integer" instead. + +```bash In scenario "Get Products. Response: Returns Product With Id" API: GET /products/(id:number) -> 200 @@ -215,34 +238,58 @@ API: GET /products/(id:number) -> 200 The newer contract is not backward compatible. ``` -Specmatic will show you an error message, saying that the change is not backward compatible. The reason for this is that existing consumers are expecting a string "sku", but will get an "integer" instead. - If the change is not backward compatible, the compare command exits with exit code 1. You can use this in a script. ## Validating Changes In Git On Your Laptop -If api_products_v1.yaml is in a git repository, and the change is backward compatible, make the change directly to the v1 file instead of creating a new one. +If `api_products_v1.yaml` is part of a git repository, changes can be made directly to this file instead of creating a new one. Then to confirm that it is a backward compatible change, before committing the change, run this command: +{% tabs git-compare %} +{% tab git-compare java %} ```bash java -jar specmatic.jar compatible git file ./run/specmatic/examples/api_products_v1.yaml ``` +{% endtab %} +{% tab git-compare docker %} +```bash +docker run -v "/git-repo:/git-repo" znsio/specmatic compatible git file "/git-repo/api_products_v1.yaml" +``` +{% endtab %} +{% endtabs %} This command exits with exit code 1 if the change is backward incompatible. It can be configured as a git pre-commit hook. +```bash +The newer contract is backward compatible +``` + ## Validating Changes In CI In CI, you will need to compare the changes in a contract from one commit to the next. You can do this with the following command: +{% tabs ci-compare %} +{% tab ci-compare java %} ```bash -> java -jar specmatic.jar compatible git commits api_products_v1.yaml HEAD HEAD^1 +java -jar specmatic.jar compatible git commits api_products_v1.yaml HEAD HEAD^1 ``` +{% endtab %} +{% tab ci-compare docker %} +```bash +docker run -v "/git-repo:/git-repo" znsio/specmatic compatible git commits "/git-repo/api_products_v1.yaml" HEAD HEAD^1 +``` +{% endtab %} +{% endtabs %} You can even use commit hashes here if you wish to compare any other pair of commits. +```bash +The newer contract is backward compatible +``` + This command exits with exit code 1 if the change is backward incompatible. ## Handling Contracts In Progress diff --git a/getting_started.md b/getting_started.md index a06d38fe0..26d763b48 100644 --- a/getting_started.md +++ b/getting_started.md @@ -103,6 +103,11 @@ specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/zn npx specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation ``` {% endtab %} +{% tab test docker %} +```shell + docker run -v "/local-directory/service.yaml:/service.yaml" znsio/specmatic test "/service.yaml" --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation +``` +{% endtab %} {% endtabs %} This should print out a result that looks something like this. @@ -132,23 +137,48 @@ Tests run: 1, Successes: 1, Failures: 0, Errors: 0 How did Specmatic know to make the exact request to ```GET /znsio/specmatic-documentation/pets/1``` with petId as "1"? And not just any other number? -If you notice the OpenAPI, we have an example section for PetId which sets up our petId as per the test data. +In the OpenAPI spec you may have noticed that there is an examples section for petid. ```yaml - name: "petid" in: "path" required: true schema: - type: "number" + type: "number" examples: - 200_OKAY: + 200_OKAY: value: 1 ``` -Try removing this example value and try running the specmatic test command again. +Remove the examples section such that the `petid` param look as shown below. + +```yaml + - name: "petid" + in: "path" + required: true + schema: + type: "number" +``` + +And try running the specmatic test command again. + +{% tabs test3 %} +{% tab test3 java %} ```shell specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation ``` +{% endtab %} +{% tab test3 npm %} +```shell +npx specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation +``` +{% endtab %} +{% tab test3 docker %} +```shell + docker run -v "/local-directory/service.yaml:/service.yaml" znsio/specmatic test "/service.yaml" --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation +``` +{% endtab %} +{% endtabs %} Specmatic will generate a random petId based on the datatype of the petId path parameter which results in a 404 since test data does not exist. ```shell @@ -177,6 +207,11 @@ specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/zn npx specmatic test service.yaml --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation ``` {% endtab %} +{% tab test2 docker %} +```shell + docker run -v "/local-directory/service.yaml:/service.yaml" znsio/specmatic test "/service.yaml" --testBaseURL=https://my-json-server.typicode.com/znsio/specmatic-documentation +``` +{% endtab %} {% endtabs %} This time around the test fails because the response from our sample app is not in line with the OpenAPI Specification. ```shell @@ -224,6 +259,11 @@ specmatic stub service.yaml npx specmatic stub service.yaml ``` {% endtab %} +{% tab stub docker %} +```shell +docker run -v "/local-directory/service.yaml:/service.yaml" -p 9000:9000 znsio/specmatic stub "/service.yaml" +``` +{% endtab %} {% endtabs %} This should start your stub server on port 9000 by default (you can switch the port number by adding ```--port ``` to the above command) as below. @@ -233,10 +273,15 @@ Loading service.yaml Stub server is running on http://0.0.0.0:9000. Ctrl + C to stop. ``` -Once the stub server is running you can verify the API by accessing it through Postman, Chrome, Curl etc. to see the response. +Once the stub server is running you can verify the API by accessing it through Postman, Chrome, Curl etc. ```shell curl http://localhost:9000/pets/123 +``` + +You should now be able to see the response that matches the schema defined in your OpenAPI spec. + +```shell { "id": 864, "name": "VRIQA", @@ -246,8 +291,8 @@ curl http://localhost:9000/pets/123 ``` The response contains auto-generated values that adhere to the data type defined in the contract. In above output petid "864" is generated by specmatic and will vary with every execution. If you would like to control the value that is being returned you can set up stub / canned responses. -* Create a folder named service_data in the same folder as your service.yaml file (_data suffix is a naming convention that tell Specmatic to look for canned responses in that directory) -* Create a json file with the name scooby.json and add below contents to it +* Create a folder named `service_data` in the same folder as your `service.yaml` file (`_data` suffix is a naming convention that tell Specmatic to look for canned responses in that directory) +* Create a json file with the name `scooby.json` and add below contents to it ```json { @@ -280,6 +325,14 @@ specmatic stub service.yaml npx specmatic stub service.yaml ``` {% endtab %} +{% tab stub2 docker %} +```shell +# Please note docker command here has to volume map the directory containing service.yaml +# to a directory within the container so that both service.yaml and folder service_data along +# with scooby.json are available to Specmatic docker container +docker run -v "/local-directory/:/specs" -p 9000:9000 znsio/specmatic stub "/specs/service.yaml" +``` +{% endtab %} {% endtabs %} This time you should see Specmatic load your canned response file also. @@ -294,6 +347,10 @@ Stub server is running on http://0.0.0.0:9000. Ctrl + C to stop. And let us now run the curl command. ```shell curl http://localhost:9000/pets/1 +``` + +Specmatic will now return your canned response for petId 1. For any other petId it will continue to return generated values. +```shell { "id": 1, "name": "Scooby", @@ -302,11 +359,9 @@ curl http://localhost:9000/pets/1 } ``` -Specmatic will now return your canned response for petId 1. For any other petId it will continue to return generated values. - So what is so smart about Specmatic Smart Mocks. -Let us try a few experiments. Remove the "status" field in scooby.json and run the stub command again. You should an output like below. +Let us try a few experiments. Remove the `status` field within http-response body in `scooby.json` and run the stub command again. You should an output like below. ```shell Loading service.yaml Loading stub expectations from //service_data