diff options
Diffstat (limited to 'doc/development/testing_guide/best_practices.md')
-rw-r--r-- | doc/development/testing_guide/best_practices.md | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md index c3125f52cf2..c44e26927fe 100644 --- a/doc/development/testing_guide/best_practices.md +++ b/doc/development/testing_guide/best_practices.md @@ -851,6 +851,47 @@ using expectations, or dependency injection along with stubs, to avoid the need for modifications. If you have no other choice, an `around` block like the global variables example can be used, but avoid this if at all possible. +#### Elasticsearch specs + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61171) in GitLab 14.0. + +Specs that require Elasticsearch must be marked with the `:elastic` trait. This +creates and deletes indices between examples to ensure a clean index, so that there is no room +for polluting the tests with nonessential data. +Most tests for Elasticsearch logic relate to: + +- Creating data in Postgres and waiting for it to be indexed in Elasticsearch. +- Searching for that data. +- Ensuring that the test gives the expected result. + +There are some exceptions, such as checking for structural changes rather than individual records in an index. + +The `:elastic_with_delete_by_query` trait was added to reduce run time for pipelines by creating and deleting indices +at the start and end of each context only. The [Elasticsearch DeleteByQuery API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html) +is used to delete data in all indices in between examples to ensure a clean index. + +Note that Elasticsearch indexing uses [`Gitlab::Redis::SharedState`](../../../ee/development/redis.md#gitlabrediscachesharedstatequeues). +Therefore, the Elasticsearch traits dynamically use the `:clean_gitlab_redis_shared_state` trait. +You do NOT need to add `:clean_gitlab_redis_shared_state` manually. + +Specs using Elasticsearch require that you: + +- Create data in Postgres and then index it into Elasticsearch. +- Enable Application Settings for Elasticsearch (which is disabled by default). + +To do so, use: + +```ruby +before do + stub_ee_application_setting(elasticsearch_search: true, elasticsearch_indexing: true) +end +``` + +Additionally, you can use the `ensure_elasticsearch_index!` method to overcome the asynchronous nature of Elasticsearch. +It uses the [Elasticsearch Refresh API](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html#refresh-api-desc) +to make sure all operations performed on an index since the last refresh are available for search. This method is typically +called after loading data into Postgres to ensure the data is indexed and searchable. + #### Test Snowplow events WARNING: @@ -954,6 +995,7 @@ Only use simple values as input in the `where` block. Using objects, FactoryBot-created objects, and similar items can lead to [unexpected results](https://github.com/tomykaira/rspec-parameterized/issues/8). <!-- vale gitlab.Spelling = YES --> + ### Prometheus tests Prometheus metrics may be preserved from one test run to another. To ensure that metrics are @@ -1034,6 +1076,16 @@ expect(json_string).to be_valid_json expect(json_string).to be_valid_json.and match_schema(schema) ``` +#### `be_one_of(collection)` + +The inverse of `include`, tests that the `collection` includes the expected +value: + +```ruby +expect(:a).to be_one_of(%i[a b c]) +expect(:z).not_to be_one_of(%i[a b c]) +``` + ### Testing query performance Testing query performance allows us to: @@ -1097,7 +1149,7 @@ module Spec module Helpers module CycleAnalyticsHelpers def create_commit_referencing_issue(issue, branch_name: random_git_name) - project.repository.add_branch(user, branch_name, 'master') + project.repository.add_branch(user, branch_name, 'main') create_commit("Commit for ##{issue.iid}", issue.project, user, branch_name) end end @@ -1154,7 +1206,7 @@ let(:project) { create(:project, :repository) } ``` Where you can, consider using the `:custom_repo` trait instead of `:repository`. -This allows you to specify exactly what files appear in the `master` branch +This allows you to specify exactly what files appear in the `main` branch of the project's repository. For example: ```ruby |