summaryrefslogtreecommitdiff
path: root/doc/development/testing_guide/contract/index.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/testing_guide/contract/index.md')
-rw-r--r--doc/development/testing_guide/contract/index.md26
1 files changed, 18 insertions, 8 deletions
diff --git a/doc/development/testing_guide/contract/index.md b/doc/development/testing_guide/contract/index.md
index 08a21e58a52..31d68bb9f4f 100644
--- a/doc/development/testing_guide/contract/index.md
+++ b/doc/development/testing_guide/contract/index.md
@@ -24,7 +24,7 @@ The contracts themselves are stored in [`/spec/contracts/contracts`](https://git
### Run the consumer tests
-Before running the consumer tests, go to `spec/contracts/consumer` and run `npm install`. To run all the consumer tests, you just need to run `npm test -- /specs`. Otherwise, to run a specific spec file, replace `/specs` with the specific spec filename.
+Before running the consumer tests, go to `spec/contracts/consumer` and run `npm install`. To run all the consumer tests, you just need to run `npm run jest:contract -- /specs`. Otherwise, to run a specific spec file, replace `/specs` with the specific spec filename. Running the consumer test will create the contract that the provider test uses to verify the actual API behavior.
You can also run tests from the root directory of the project, using the command `yarn jest:contract`.
@@ -40,6 +40,14 @@ rake contracts:merge_requests:pact:verify:discussions
rake contracts:merge_requests:test:merge_requests[contract_merge_requests] # Run all merge request contract tests
```
+#### Verify the contracts in Pact Broker
+
+By default, the Rake tasks will verify the locally stored contracts. In order to verify the contracts published in the Pact Broker, we need to set the `PACT_BROKER` environment variable to `true`. It is important to point out here that the file path and file name of the provider test is what is used to find the contract in the Pact Broker which is why it is important to make sure the [provider test naming conventions](#provider-naming) are followed.
+
+## Publish contracts to Pact Broker
+
+The contracts generated by the consumer test can be published to a hosted Pact Broker by going to `spec/contracts` and running the `publish-contracts.sh` script.
+
## Test suite folder structure and naming conventions
To keep the consumer and provider test suite organized and maintainable, it's important that tests are organized, also that consumers and providers are named consistently. Therefore, it's important to adhere to the following conventions.
@@ -50,31 +58,33 @@ Having an organized and sensible folder structure for the test suite makes it ea
#### Consumer tests
-The consumer tests are grouped according to the different pages in the application. Each file contains various types of requests found in a page. As such, the consumer test files are named using the Rails standards of how pages are referenced. For example, the project pipelines page would be the `Project::Pipeline#index` page so the equivalent consumer test would be located in `consumer/specs/project/pipelines/index.spec.js`.
+The consumer tests are grouped according to the different pages in the application. Each file contains various types of requests found in a page. As such, the consumer test files are named using the Rails standards of how pages are referenced. For example, the project pipelines page would be the `Project::Pipelines#index` page so the equivalent consumer test would be located in `consumer/specs/project/pipelines/index.spec.js`.
When defining the location to output the contract generated by the test, we want to follow the same file structure which would be `contracts/project/pipelines/` for this example. This is the structure in `consumer/resources` and `consumer/fixtures` as well.
+The naming of the folders must also be pluralized to match how they are called in the Rails naming standard.
+
#### Provider tests
The provider tests are grouped similarly to our controllers. Each of these tests contains various tests for an API endpoint. For example, the API endpoint to get a list of pipelines for a project would be located in `provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb`. The provider states are grouped according to the different pages in the application similar to the consumer tests.
### Naming conventions
-When writing the consumer and provider tests, there are parts where a name is required for the consumer and provider. Since there are no restrictions imposed by Pact on how these should be named, a naming convention is important to keep it easy for us to figure out which consumer and provider tests are involved during debugging. Pact also uses the consumer and provider names to generate the generated contracts in the `#{consumer_name}-#{provider_name}` format.
+When writing the consumer and provider tests, there are parts where a name is required for the consumer and provider. Since there are no restrictions imposed by Pact on how these should be named, a naming convention is important to keep it easy for us to figure out which consumer and provider tests are involved during debugging. Pact also uses the consumer and provider names to create the locally stored contract file names in the `#{consumer_name}-#{provider_name}` format.
#### Consumer naming
-As mentioned in the [folder structure section](#consumer-tests), consumer tests are grouped according to the different pages in the application. As such, consumer names should follow the same naming format using the Rails standard. For example, the consumer test for `Project::Pipeline#index` would be `ProjectPipeline#index` as the consumer name. Since Pact uses this name to name the contracts it generates, the colons (`::`) are dropped as colons are not valid characters in file names.
+As mentioned in the [folder structure section](#consumer-tests), consumer tests are grouped according to the different pages in the application. As such, consumer names should follow the same naming format using the Rails standard. For example, the consumer test for `Project::Pipelines#index` would be under the `project` folder and will be called `Pipelines#index` as the consumer name.
#### Provider naming
-These are the API endpoints that provides the data to the consumer so they are named according to the API endpoint they pertain to. Be mindful that this name is as descriptive as possible. For example, if we're writing a test for the `GET /groups/:id/projects` endpoint, we don't want to name it "Projects endpoint" as there is a `GET /projects` endpoint as well that also fetches a list of projects the user has access to across all of GitLab. An easy way to name them is by checking out our [API documentation](../../../api/api_resources.md) and naming it the same way it is named in there. So the [`GET /groups/:id/projects`](../../../api/groups.md#list-a-groups-projects) would be called `List a group’s projects` and [`GET /projects`](../../../api/projects.md#list-all-projects) would be called `List all projects`. Subsequently, the test files are named `list_a_groups_projects_helper.rb` and `list_all_projects_helper.rb` respectively.
+These are the API endpoints that provides the data to the consumer so they are named according to the API endpoint they pertain to. Be mindful that this begins with the HTTP request method and the rest of the name is as descriptive as possible. For example, if we're writing a test for the `GET /groups/:id/projects` endpoint, we don't want to name it "GET projects endpoint" as there is a `GET /projects` endpoint as well that also fetches a list of projects the user has access to across all of GitLab. To choose an appropriate name, we can start by checking out our [API documentation](../../../api/api_resources.md) and naming it the same way it is named in there while making sure to keep the name in sentence case. So the [`GET /groups/:id/projects`](../../../api/groups.md#list-a-groups-projects) would be called `GET list a group's projects` and [`GET /projects`](../../../api/projects.md#list-all-projects) would be called `GET list all projects`. Subsequently, the test files are named `get_list_a_groups_projects_helper.rb` and `get_list_all_projects_helper.rb` respectively.
-There are some cases where the provider being tested may not be documented so, in those cases, fall back to choosing a name that is as descriptive as possible to ensure it's easy to tell what the provider is for.
+There are some cases where the provider being tested may not be documented so, in those cases, fall back to starting with the HTTP request method followed by a name that is as descriptive as possible to ensure it's easy to tell what the provider is for.
#### Conventions summary
| Tests | Folder structure | Naming convention |
| ----- | ---------------- | ----------------- |
-| Consumer Test | Follows the Rails reference standards. For example, `Project::Pipeline#index` would be `consumer/specs/project/pipelines/index.spec.js` | Follows the Rails naming standard. For example, `Project::Pipeline#index` would be `ProjectPipeline#index` |
-| Provider Test | Grouped like the Rails controllers. For example, [`List project pipelines` API endpoint](../../../api/pipelines.md#list-project-pipelines) would be `provider/pact_helpers/project/pipelines/provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb` | Follows the API documentation naming scheme. For example, [`GET /projects/:id/pipelines`](../../../api/pipelines.md#list-project-pipelines) would be called `List project pipelines`. |
+| Consumer Test | Follows the Rails reference standards. For example, `Project::Pipelines#index` would be `consumer/specs/project/pipelines/index.spec.js` | Follows the Rails naming standard. For example, `Project::Pipelines#index` would be `Pipelines#index` within the `project` folder. |
+| Provider Test | Grouped like the Rails controllers. For example, [`GET list project pipelines` API endpoint](../../../api/pipelines.md#list-project-pipelines) would be `provider/pact_helpers/project/pipelines/provider/pact_helpers/project/pipelines/get_list_project_pipelines_helper.rb` | Follows the API documentation naming scheme in sentence case. For example, [`GET /projects/:id/pipelines`](../../../api/pipelines.md#list-project-pipelines) would be called `GET list project pipelines`. |