diff options
Diffstat (limited to 'doc/development/testing_guide')
10 files changed, 186 insertions, 133 deletions
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md index ac5f1a47f9b..79ff46ae352 100644 --- a/doc/development/testing_guide/best_practices.md +++ b/doc/development/testing_guide/best_practices.md @@ -13,13 +13,13 @@ description: "GitLab development guidelines - testing best practices." Testing at GitLab is a first class citizen, not an afterthought. It's important we consider the design of our tests as we do the design of our features. -When implementing a feature, we think about developing the right capabilities the right way, which helps us +When implementing a feature, we think about developing the right capabilities the right way. This helps us narrow our scope to a manageable level. When implementing tests for a feature, we must think about developing -the right tests, but then cover _all_ the important ways the test may fail, which can quickly widen our scope to +the right tests, but then cover _all_ the important ways the test may fail. This can quickly widen our scope to a level that is difficult to manage. Test heuristics can help solve this problem. They concisely address many of the common ways bugs -manifest themselves within our code. When designing our tests, take time to review known test heuristics to inform +manifest themselves in our code. When designing our tests, take time to review known test heuristics to inform our test design. We can find some helpful heuristics documented in the Handbook in the [Test Engineering](https://about.gitlab.com/handbook/engineering/quality/test-engineering/#test-heuristics) section. @@ -90,7 +90,7 @@ Obviously we should reduce test dependencies, and avoiding capabilities also reduces the amount of set-up needed. `:js` is particularly important to avoid. This must only be used if the feature -test requires JavaScript reactivity in the browser, since using a headless +test requires JavaScript reactivity in the browser. Using a headless browser is much slower than parsing the HTML response from the app. #### Optimize factory usage @@ -108,8 +108,8 @@ To avoid creation, it is worth bearing in mind that: - `instance_double` and `spy` are faster than `FactoryBot.build(...)`. - `FactoryBot.build(...)` and `.build_stubbed` are faster than `.create`. -- Don't `create` an object when `build`, `build_stubbed`, `attributes_for`, - `spy`, or `instance_double` will do. Database persistence is slow! +- Don't `create` an object when you can use `build`, `build_stubbed`, `attributes_for`, + `spy`, or `instance_double`. Database persistence is slow! Use [Factory Doctor](https://test-prof.evilmartians.io/#/profilers/factory_doctor) to find cases where database persistence is not needed in a given test. @@ -171,14 +171,14 @@ RSpec.describe API::Search, factory_default: :keep do let_it_be(:namespace) { create_default(:namespace) } ``` -Then every project we create will use this `namespace`, without us having to pass +Then every project we create uses this `namespace`, without us having to pass it as `namespace: namespace`. In order to make it work along with `let_it_be`, `factory_default: :keep` -must be explicitly specified. That will keep the default factory for every example in a suite instead of +must be explicitly specified. That keeps the default factory for every example in a suite instead of recreating it for each example. Maybe we don't need to create 208 different projects - we can create one and reuse it. In addition, we can see that only about 1/3 of the -projects we create are ones we ask for (76/208), so there is benefit in setting +projects we create are ones we ask for (76/208). There is benefit in setting a default value for projects as well: ```ruby @@ -233,8 +233,8 @@ Finished in 2 minutes 19 seconds (files took 1 minute 4.42 seconds to load) ``` From this result, we can see the most expensive examples in our spec, giving us -a place to start. The fact that the most expensive examples here are in -shared examples means that any reductions are likely to have a larger impact as +a place to start. The most expensive examples here are in +shared examples; any reductions generally have a larger impact as they are called in multiple places. #### Avoid repeating expensive actions @@ -287,7 +287,7 @@ results are available, and not just the first failure. - Use `.method` to describe class methods and `#method` to describe instance methods. - Use `context` to test branching logic. -- Try to match the ordering of tests to the ordering within the class. +- Try to match the ordering of tests to the ordering in the class. - Try to follow the [Four-Phase Test](https://thoughtbot.com/blog/four-phase-test) pattern, using newlines to separate phases. - Use `Gitlab.config.gitlab.host` rather than hard coding `'localhost'` @@ -295,10 +295,10 @@ results are available, and not just the first failure. [Gotchas](../gotchas.md#do-not-assert-against-the-absolute-value-of-a-sequence-generated-attribute)). - Avoid using `expect_any_instance_of` or `allow_any_instance_of` (see [Gotchas](../gotchas.md#do-not-assert-against-the-absolute-value-of-a-sequence-generated-attribute)). -- Don't supply the `:each` argument to hooks since it's the default. +- Don't supply the `:each` argument to hooks because it's the default. - On `before` and `after` hooks, prefer it scoped to `:context` over `:all` - When using `evaluate_script("$('.js-foo').testSomething()")` (or `execute_script`) which acts on a given element, - use a Capybara matcher beforehand (e.g. `find('.js-foo')`) to ensure the element actually exists. + use a Capybara matcher beforehand (such as `find('.js-foo')`) to ensure the element actually exists. - Use `focus: true` to isolate parts of the specs you want to run. - Use [`:aggregate_failures`](https://relishapp.com/rspec/rspec-core/docs/expectation-framework-integration/aggregating-failures) when there is more than one expectation in a test. - For [empty test description blocks](https://github.com/rubocop-hq/rspec-style-guide#it-and-specify), use `specify` rather than `it do` if the test is self-explanatory. @@ -343,7 +343,7 @@ writing one](testing_levels.md#consider-not-writing-a-system-test)! For instance, if you want to verify that a record was created, add expectations that its attributes are displayed on the page, not that `Model.count` increased by one. -- It's ok to look for DOM elements but don't abuse it since it makes the tests +- It's ok to look for DOM elements, but don't abuse it, because it makes the tests more brittle #### Debugging Capybara @@ -353,7 +353,7 @@ Sometimes you may need to debug Capybara tests by observing browser behavior. #### Live debug You can pause Capybara and view the website on the browser by using the -`live_debug` method in your spec. The current page will be automatically opened +`live_debug` method in your spec. The current page is automatically opened in your default browser. You may need to sign in first (the current user's credentials are displayed in the terminal). @@ -381,13 +381,13 @@ Finished in 34.51 seconds (files took 0.76702 seconds to load) #### Run `:js` spec in a visible browser -Run the spec with `CHROME_HEADLESS=0`, e.g.: +Run the spec with `CHROME_HEADLESS=0`, like this: ```shell CHROME_HEADLESS=0 bin/rspec some_spec.rb ``` -The test will go by quickly, but this will give you an idea of what's happening. +The test completes quickly, but this gives you an idea of what's happening. Using `live_debug` with `CHROME_HEADLESS=0` pauses the open browser, and does not open the page again. This can be used to debug and inspect elements. @@ -416,20 +416,20 @@ There is a [small hack](https://gitlab.com/gitlab-org/gitlab-foss/snippets/17184 ### Fast unit tests -Some classes are well-isolated from Rails and you should be able to test them +Some classes are well-isolated from Rails. You should be able to test them without the overhead added by the Rails environment and Bundler's `:default` group's gem loading. In these cases, you can `require 'fast_spec_helper'` instead of `require 'spec_helper'` in your test file, and your test should run -really fast since: +really fast because: -- Gems loading is skipped +- Gem loading is skipped - Rails app boot is skipped - GitLab Shell and Gitaly setup are skipped - Test repositories setup are skipped `fast_spec_helper` also support autoloading classes that are located inside the -`lib/` directory. It means that as long as your class / module is using only -code from the `lib/` directory you will not need to explicitly load any +`lib/` directory. If your class or module is using only +code from the `lib/` directory, you don't need to explicitly load any dependencies. `fast_spec_helper` also loads all ActiveSupport extensions, including core extensions that are commonly used in the Rails environment. @@ -439,9 +439,11 @@ in `lib/`. For example, if you want to test your code that is calling the `Gitlab::UntrustedRegexp` class, which under the hood uses `re2` library, you -should either add `require_dependency 're2'` to files in your library that -need `re2` gem, to make this requirement explicit, or you can add it to the -spec itself, but the former is preferred. +should either: + +- Add `require_dependency 're2'` to files in your library that need `re2` gem, + to make this requirement explicit. This approach is preferred. +- Add it to the spec itself. It takes around one second to load tests that are using `fast_spec_helper` instead of 30+ seconds in case of a regular `spec_helper`. @@ -465,7 +467,7 @@ so we need to set some guidelines for their use going forward: - Don't define a `let` variable that's only used by the definition of another. Use a helper method instead. - `let!` variables should be used only in case if strict evaluation with defined - order is required, otherwise `let` will suffice. Remember that `let` is lazy and won't + order is required, otherwise `let` suffices. Remember that `let` is lazy and won't be evaluated until it is referenced. - Avoid referencing `subject` in examples. Use a named subject `subject(:name)`, or a `let` variable instead, so the variable has a contextual name. @@ -475,7 +477,7 @@ so we need to set some guidelines for their use going forward: In some cases, there is no need to recreate the same object for tests again for each example. For example, a project and a guest of that project -is needed to test issues on the same project, one project and user will do for the entire file. +are needed to test issues on the same project, so one project and user are enough for the entire file. As much as possible, do not implement this using `before(:all)` or `before(:context)`. If you do, you would need to manually clean up the data as those hooks run outside a database transaction. @@ -494,9 +496,9 @@ before_all do end ``` -This will result in only one `Project`, `User`, and `ProjectMember` created for this context. +This results in only one `Project`, `User`, and `ProjectMember` created for this context. -`let_it_be` and `before_all` are also available within nested contexts. Cleanup after the context +`let_it_be` and `before_all` are also available in nested contexts. Cleanup after the context is handled automatically using a transaction rollback. Note that if you modify an object defined inside a `let_it_be` block, @@ -545,14 +547,14 @@ This section was moved to [developing with feature flags](../feature_flags/devel The code exercised by a single GitLab test may access and modify many items of data. Without careful preparation before a test runs, and cleanup afterward, -data can be changed by a test in such a way that it affects the behavior of +a test can change data in a way that affects the behavior of following tests. This should be avoided at all costs! Fortunately, the existing test framework handles most cases already. When the test environment does get polluted, a common outcome is -[flaky tests](flaky_tests.md). Pollution will often manifest as an order -dependency: running spec A followed by spec B will reliably fail, but running -spec B followed by spec A will reliably succeed. In these cases, you can use +[flaky tests](flaky_tests.md). Pollution often manifests as an order +dependency: running spec A followed by spec B reliably fails, but running +spec B followed by spec A reliably succeeds. In these cases, you can use `rspec --bisect` (or a manual pairwise bisect of spec files) to determine which spec is at fault. Fixing the problem requires some understanding of how the test suite ensures the environment is pristine. Read on to discover more about each @@ -561,15 +563,15 @@ data store! #### SQL database This is managed for us by the `database_cleaner` gem. Each spec is surrounded in -a transaction, which is rolled back once the test completes. Certain specs will -instead issue `DELETE FROM` queries against every table after completion; this +a transaction, which is rolled back after the test completes. Certain specs +instead issue `DELETE FROM` queries against every table after completion. This allows the created rows to be viewed from multiple database connections, which is important for specs that run in a browser, or migration specs, among others. One consequence of using these strategies, instead of the well-known `TRUNCATE TABLES` approach, is that primary keys and other sequences are **not** reset across specs. So if you create a project in spec A, then create a project -in spec B, the first will have `id=1`, while the second will have `id=2`. +in spec B, the first has `id=1`, while the second has `id=2`. This means that specs should **never** rely on the value of an ID, or any other sequence-generated column. To avoid accidental conflicts, specs should also @@ -610,7 +612,7 @@ DNS requests are stubbed universally in the test suite (as of [!22368](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22368)), as DNS can cause issues depending on the developer's local network. There are RSpec labels available in `spec/support/dns.rb` which you can apply to tests if you need to -bypass the DNS stubbing, e.g.: +bypass the DNS stubbing, like this: ```ruby it "really connects to Prometheus", :permit_dns do @@ -625,8 +627,8 @@ In the situations where you need to [stub](https://relishapp.com/rspec/rspec-mocks/v/3-9/docs/basics/allowing-messages) methods such as `File.read`, make sure to: -1. Stub `File.read` for only the filepath you are interested in. -1. Call the original implementation for other filepaths. +1. Stub `File.read` for only the file path you are interested in. +1. Call the original implementation for other file paths. Otherwise `File.read` calls from other parts of the codebase get stubbed incorrectly. You should use the `stub_file_read`, and @@ -645,19 +647,19 @@ allow(File).to receive(:read).and_call_original allow(File).to receive(:read).with(my_filepath) ``` -#### Filesystem +#### File system -Filesystem data can be roughly split into "repositories", and "everything else". +File system data can be roughly split into "repositories", and "everything else". Repositories are stored in `tmp/tests/repositories`. This directory is emptied before a test run starts, and after the test run ends. It is not emptied between -specs, so created repositories accumulate within this directory over the +specs, so created repositories accumulate in this directory over the lifetime of the process. Deleting them is expensive, but this could lead to pollution unless carefully managed. To avoid this, [hashed storage](../../administration/repository_storage_types.md) is enabled in the test suite. This means that repositories are given a unique -path that depends on their project's ID. Since the project IDs are not reset -between specs, this guarantees that each spec gets its own repository on disk, +path that depends on their project's ID. Because the project IDs are not reset +between specs, each spec gets its own repository on disk, and prevents changes from being visible between specs. If a spec manually specifies a project ID, or inspects the state of the @@ -671,9 +673,9 @@ written to disk in locations determined by ID, so conflicts should not occur. Some specs disable hashed storage by passing the `:legacy_storage` trait to the `projects` factory. Specs that do this must **never** override the `path` of the -project, or any of its groups. The default path includes the project ID, so will -not conflict; but if two specs create a `:legacy_storage` project with the same -path, they will use the same repository on disk and lead to test environment +project, or any of its groups. The default path includes the project ID, so it +does not conflict. If two specs create a `:legacy_storage` project with the same +path, they use the same repository on disk and lead to test environment pollution. Other files must be managed manually by the spec. If you run code that creates a @@ -712,21 +714,20 @@ If you need to modify the contents of the `ENV` constant, you can use the While most Ruby **instances** are not shared between specs, **classes** and **modules** generally are. Class and module instance variables, accessors, class variables, and other stateful idioms, should be treated in the same way as -global variables - don't modify them unless you have to! In particular, prefer +global variables. Don't modify them unless you have to! In particular, prefer using expectations, or dependency injection along with stubs, to avoid the need -for modifications. If you have no other choice, an `around` block similar to the -example for global variables, above, can be used, but this should be avoided if -at all possible. +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. #### Test Snowplow events WARNING: Snowplow performs **runtime type checks** by using the [contracts gem](https://rubygems.org/gems/contracts). -Since Snowplow is **by default disabled in tests and development**, it can be hard to +Because Snowplow is **by default disabled in tests and development**, it can be hard to **catch exceptions** when mocking `Gitlab::Tracking`. -To catch runtime errors due to type checks, you can enable Snowplow in tests by marking the spec with -`:snowplow` and use the `expect_snowplow_event` helper which will check for +To catch runtime errors due to type checks, you can enable Snowplow in tests. Mark the spec with +`:snowplow` and use the `expect_snowplow_event` helper, which checks for calls to `Gitlab::Tracking#event`. ```ruby @@ -737,12 +738,14 @@ describe '#show', :snowplow do expect_snowplow_event( category: 'Experiment', action: 'start', + standard_context: { namespace: group, project: project } ) expect_snowplow_event( category: 'Experiment', action: 'sent', property: 'property', - label: 'label' + label: 'label', + standard_context: { namespace: group, project: project } ) end end @@ -794,7 +797,7 @@ end WARNING: Only use simple values as input in the `where` block. Using procs, stateful -objects, FactoryBot-created objects etc. can lead to +objects, FactoryBot-created objects, and similar items can lead to [unexpected results](https://github.com/tomykaira/rspec-parameterized/issues/8). ### Prometheus tests @@ -807,7 +810,7 @@ reset before each example, add the `:prometheus` tag to the RSpec test. Custom matchers should be created to clarify the intent and/or hide the complexity of RSpec expectations. They should be placed under `spec/support/matchers/`. Matchers can be placed in subfolder if they apply to -a certain type of specs only (e.g. features, requests etc.) but shouldn't be if +a certain type of specs only (such as features or requests) but shouldn't be if they apply to multiple type of specs. #### `be_like_time` @@ -881,13 +884,13 @@ expect(json_string).to be_valid_json.and match_schema(schema) Testing query performance allows us to: -- Assert that N+1 problems do not exist within a block of code. -- Ensure that the number of queries within a block of code does not increase unnoticed. +- Assert that N+1 problems do not exist in a block of code. +- Ensure that the number of queries in a block of code does not increase unnoticed. #### QueryRecorder `QueryRecorder` allows profiling and testing of the number of database queries -performed within a given block of code. +performed in a given block of code. See the [`QueryRecorder`](../query_recorder.md) section for more details. @@ -905,9 +908,9 @@ Any shared contexts used by more than one spec file: - Should be placed under `spec/support/shared_contexts/`. - Can be placed in subfolder if they apply to a certain type of specs only - (e.g. features, requests etc.) but shouldn't be if they apply to multiple type of specs. + (such as features or requests) but shouldn't be if they apply to multiple type of specs. -Each file should include only one context and have a descriptive name, e.g. +Each file should include only one context and have a descriptive name, such as `spec/support/shared_contexts/controllers/githubish_import_controller_shared_context.rb`. ### Shared examples @@ -917,9 +920,9 @@ Any shared examples used by more than one spec file: - Should be placed under `spec/support/shared_examples/`. - Can be placed in subfolder if they apply to a certain type of specs only - (e.g. features, requests etc.) but shouldn't be if they apply to multiple type of specs. + (such as features or requests) but shouldn't be if they apply to multiple type of specs. -Each file should include only one context and have a descriptive name, e.g. +Each file should include only one context and have a descriptive name, such as `spec/support/shared_examples/controllers/githubish_import_controller_shared_example.rb`. ### Helpers @@ -927,8 +930,8 @@ Each file should include only one context and have a descriptive name, e.g. Helpers are usually modules that provide some methods to hide the complexity of specific RSpec examples. You can define helpers in RSpec files if they're not intended to be shared with other specs. Otherwise, they should be placed -under `spec/support/helpers/`. Helpers can be placed in subfolder if they apply -to a certain type of specs only (e.g. features, requests etc.) but shouldn't be +under `spec/support/helpers/`. Helpers can be placed in a subfolder if they apply +to a certain type of specs only (such as features or requests) but shouldn't be if they apply to multiple type of specs. Helpers should follow the Rails naming / namespacing convention. For instance @@ -985,7 +988,7 @@ All fixtures should be placed under `spec/fixtures/`. ### Repositories -Testing some functionality, e.g., merging a merge request, requires a Git +Testing some functionality, such as merging a merge request, requires a Git repository with a certain state to be present in the test environment. GitLab maintains the [`gitlab-test`](https://gitlab.com/gitlab-org/gitlab-test) repository for certain common cases - you can ensure a copy of the repository is @@ -996,7 +999,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 will appear in the `master` branch +This allows you to specify exactly what files appear in the `master` branch of the project's repository. For example: ```ruby @@ -1011,17 +1014,17 @@ let(:project) do end ``` -This will create a repository containing two files, with default permissions and +This creates a repository containing two files, with default permissions and the specified content. ### Configuration -RSpec configuration files are files that change the RSpec configuration (i.e. +RSpec configuration files are files that change the RSpec configuration (like `RSpec.configure do |config|` blocks). They should be placed under `spec/support/`. -Each file should be related to a specific domain, e.g. -`spec/support/capybara.rb`, `spec/support/carrierwave.rb`, etc. +Each file should be related to a specific domain, such as +`spec/support/capybara.rb` or `spec/support/carrierwave.rb`. If a helpers module applies only to a certain kind of specs, it should add modifiers to the `config.include` call. For instance if @@ -1047,7 +1050,7 @@ file which is used by the `spec/fast_spec_helper.rb` file. See Services for the test environment are automatically configured and started when tests are run, including Gitaly, Workhorse, Elasticsearch, and Capybara. When run in CI, or -if the service needs to be installed, the test environment will log information +if the service needs to be installed, the test environment logs information about set-up time, producing log messages like the following: ```plaintext diff --git a/doc/development/testing_guide/end_to_end/best_practices.md b/doc/development/testing_guide/end_to_end/best_practices.md index b761e33367f..a5a2d2a1113 100644 --- a/doc/development/testing_guide/end_to_end/best_practices.md +++ b/doc/development/testing_guide/end_to_end/best_practices.md @@ -10,7 +10,7 @@ This is a tailored extension of the Best Practices [found in the testing guide]( ## Link a test to its test-case issue -Every test should have a corresponding issue in the [Quality Testcases project](https://gitlab.com/gitlab-org/quality/testcases/). +Every test should have a corresponding issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/). It's recommended that you reuse the issue created to plan the test. If one does not already exist you can create the issue yourself. Alternatively, you can run the test in a pipeline that has reporting enabled and the test-case issue reporter will automatically create a new issue. @@ -244,7 +244,7 @@ point of failure and so the screenshot would not be captured at the right moment All tests expect to be able to log in at the start of the test. -For an example see: <https://gitlab.com/gitlab-org/gitlab/-/issues/34736> +For an example see [issue #34736](https://gitlab.com/gitlab-org/gitlab/-/issues/34736). Ideally, actions performed in an `after(:context)` (or [`before(:context)`](#limit-the-use-of-the-ui-in-beforecontext-and-after-hooks)) diff --git a/doc/development/testing_guide/end_to_end/feature_flags.md b/doc/development/testing_guide/end_to_end/feature_flags.md index 1e0eda6491a..1bc33b79c7c 100644 --- a/doc/development/testing_guide/end_to_end/feature_flags.md +++ b/doc/development/testing_guide/end_to_end/feature_flags.md @@ -74,3 +74,16 @@ existing tests or write new ones. Please see the [QA README](https://gitlab.com/gitlab-org/gitlab/tree/master/qa#running-tests-with-a-feature-flag-enabled) for details. + +## Confirming that end-to-end tests pass with a feature flag enabled + +End-to-end tests should pass with a feature flag enabled before it is enabled on Staging or on GitLab.com. Tests that need to be updated should be identified as part of [quad-planning](https://about.gitlab.com/handbook/engineering/quality/quad-planning/). The relevant [counterpart Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors) is responsible for updating the tests or assisting another engineer to do so. However, if a change does not go through quad-planning and a required test update is not made, test failures could block deployment. + +If a test enables a feature flag as describe above, it is sufficient to run the `package-and-qa` job in a merge request containing the relevant changes. +Or, if the feature flag and relevant changes have already been merged, you can confirm that the tests +pass on `master`. The end-to-end tests run on `master` every two hours, and the results are posted to a [Test +Session Report, which is available in the testcase-sessions project](https://gitlab.com/gitlab-org/quality/testcase-sessions/-/issues?label_name%5B%5D=found%3Amaster). + +If the relevant tests do not enable the feature flag themselves, you can check if the tests will need +to be updated by opening a draft merge request that enables the flag by default and then running the `package-and-qa` job. +The merge request can be closed once the tests pass. If you need assistance to update the tests, please contact the relevant [stable counterpart in the Quality department](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors), or any Software Engineer in Test if there is no stable counterpart for your group. diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md index 939e44cedd9..d9309f74e0e 100644 --- a/doc/development/testing_guide/end_to_end/page_objects.md +++ b/doc/development/testing_guide/end_to_end/page_objects.md @@ -145,7 +145,7 @@ for each element defined. In our case, `data-qa-selector="login_field"`, `data-qa-selector="password_field"` and `data-qa-selector="sign_in_button"` -**app/views/my/view.html.haml** +`app/views/my/view.html.haml` ```haml = f.text_field :login, class: "form-control top", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required.", data: { qa_selector: 'login_field' } diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md index 6d6f7fbcf8d..8a929737ebe 100644 --- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md +++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md @@ -14,31 +14,32 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec | Tag | Description | |-----|-------------| | `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. | +| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. | | `:gitaly_cluster` | The test runs against a GitLab instance where repositories are stored on redundant Gitaly nodes behind a Praefect node. All nodes are [separate containers](../../../administration/gitaly/praefect.md#requirements-for-configuring-a-gitaly-cluster). Tests that use this tag have a longer setup time since there are three additional containers that need to be started. | +| `:github` | The test requires a GitHub personal access token. | +| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | +| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | | `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) provisions the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run. | `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test also includes provisioning of at least one Kubernetes cluster to test against. _This tag is often be paired with `:orchestrated`._ | +| `:ldap_no_server` | The test requires a GitLab instance to be configured to use LDAP. To be used with the `:orchestrated` tag. It does not spin up an LDAP server at orchestration time. Instead, it creates the LDAP server at runtime. | +| `:ldap_no_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS not enabled. | +| `:ldap_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS enabled. | +| `:mattermost` | The test requires a GitLab Mattermost service on the GitLab instance. | +| `:object_storage` | The test requires a GitLab instance to be configured to use multiple [object storage types](../../../administration/object_storage.md). Uses MinIO as the object storage server. | | `:only` | The test is only to be run against specific environments or pipelines. See [Environment selection](environment_selection.md) for more information. | | `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate Docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify the GitLab configuration (for example, Staging). | +| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. | | `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), runs in a separate job that only includes quarantined tests, and is allowed to fail. The test is skipped in its regular job so that if it fails it doesn't hold up the pipeline. Note that you can also [quarantine a test only when it runs against specific environment](environment_selection.md#quarantining-a-test-for-a-specific-environment). | +| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). | | `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/guidelines/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. | +| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. | | `:requires_admin` | The test requires an admin account. Tests with the tag are excluded when run against Canary and Production environments. | +| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. | +| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. | | `:runner` | The test depends on and sets up a GitLab Runner instance, typically to run a pipeline. | | `:skip_live_env` | The test is excluded when run against live deployed environments such as Staging, Canary, and Production. | -| `:testcase` | The link to the test case issue in the [Quality Testcases project](https://gitlab.com/gitlab-org/quality/testcases/). | -| `:mattermost` | The test requires a GitLab Mattermost service on the GitLab instance. | -| `:ldap_no_server` | The test requires a GitLab instance to be configured to use LDAP. To be used with the `:orchestrated` tag. It does not spin up an LDAP server at orchestration time. Instead, it creates the LDAP server at runtime. | -| `:ldap_no_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS not enabled. | -| `:ldap_tls` | The test requires a GitLab instance to be configured to use an external LDAP server with TLS enabled. | -| `:object_storage` | The test requires a GitLab instance to be configured to use multiple [object storage types](../../../administration/object_storage.md). Uses MinIO as the object storage server. | -| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. | -| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | -| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. | | `:skip_signup_disabled` | The test uses UI to sign up a new user and is skipped in any environment that does not allow new user registration via the UI. | | `:smoke` | The test belongs to the test suite which verifies basic functionality of a GitLab instance.| -| `:github` | The test requires a GitHub personal access token. | -| `:repository_storage` | The test requires a GitLab instance to be configured to use multiple [repository storage paths](../../../administration/repository_storage_paths.md). Paired with the `:orchestrated` tag. | -| `:geo` | The test requires two GitLab Geo instances - a primary and a secondary - to be spun up. | -| `:relative_url` | The test requires a GitLab instance to be installed under a [relative URL](../../../install/relative_url.md). | -| `:requires_git_protocol_v2` | The test requires that Git protocol version 2 is enabled on the server. It's assumed to be enabled by default but if not the test can be skipped by setting `QA_CAN_TEST_GIT_PROTOCOL_V2` to `false`. | -| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. | -| `:packages` | The test requires a GitLab instance that has the [Package Registry](../../../administration/packages/#gitlab-package-registry-administration) enabled. | +| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. | +| `:testcase` | The link to the test case issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/). | +| `:transient` | The test tests transient bugs. It is excluded by default. | diff --git a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md index cd429a74a2a..b6293ec41b8 100644 --- a/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md +++ b/doc/development/testing_guide/end_to_end/running_tests_that_require_special_setup.md @@ -75,17 +75,17 @@ When all the containers are running, the output of the `docker ps` command shows ```plaintext CONTAINER ID ... PORTS NAMES -d15d3386a0a8 ... 22/tcp, 443/tcp, 0.0.0.0:32772->80/tcp gitlab-gitaly-ha +d15d3386a0a8 ... 22/tcp, 443/tcp, 0.0.0.0:32772->80/tcp gitlab-gitaly-cluster ``` -That shows that the GitLab instance running in the `gitlab-gitaly-ha` container can be reached via `http://localhost:32772`. However, Git operations like cloning and pushing are performed against the URL revealed via the UI as the clone URL. It uses the hostname configured for the GitLab instance, which in this case matches the Docker container name and network, `gitlab-gitaly-ha.test`. Before you can run the tests you need to configure your computer to access the container via that address. One option is to [use caddyserver as described for running tests against GDK](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/run_qa_against_gdk.md#workarounds). +That shows that the GitLab instance running in the `gitlab-gitaly-cluster` container can be reached via `http://localhost:32772`. However, Git operations like cloning and pushing are performed against the URL revealed via the UI as the clone URL. It uses the hostname configured for the GitLab instance, which in this case matches the Docker container name and network, `gitlab-gitaly-cluster.test`. Before you can run the tests you need to configure your computer to access the container via that address. One option is to [use Caddy server as described for running tests against GDK](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/run_qa_against_gdk.md#workarounds). Another option is to use NGINX. -In both cases you must configure your machine to translate `gitlab-gitlab-ha.test` into an appropriate IP address: +In both cases you must configure your machine to translate `gitlab-gitaly-cluster.test` into an appropriate IP address: ```shell -echo '127.0.0.1 gitlab-gitaly-ha.test' | sudo tee -a /etc/hosts +echo '127.0.0.1 gitlab-gitaly-cluster.test' | sudo tee -a /etc/hosts ``` Then install NGINX: @@ -101,19 +101,19 @@ apt install nginx yum install nginx ``` -Finally, configure NGINX to pass requests for `gitlab-gitaly-ha.test` to the GitLab instance: +Finally, configure NGINX to pass requests for `gitlab-gitaly-cluster.test` to the GitLab instance: ```plaintext # On Debian/Ubuntu, in /etc/nginx/sites-enabled/gitlab-cluster # On macOS, in /usr/local/etc/nginx/nginx.conf server { - server_name gitlab-gitaly-ha.test; + server_name gitlab-gitaly-cluster.test; client_max_body_size 500m; location / { proxy_pass http://127.0.0.1:32772; - proxy_set_header Host gitlab-gitaly-ha.test; + proxy_set_header Host gitlab-gitaly-cluster.test; } } ``` @@ -131,14 +131,14 @@ sudo nginx -s reload You could then run the tests from the `/qa` directory: ```shell -CHROME_HEADLESS=false bin/qa Test::Instance::All http://gitlab-gitaly-ha.test -- --tag gitaly_ha +CHROME_HEADLESS=false bin/qa Test::Instance::All http://gitlab-gitaly-cluster.test -- --tag gitaly_cluster ``` Once you have finished testing you can stop and remove the Docker containers: ```shell -docker stop gitlab-gitaly-ha praefect postgres gitaly3 gitaly2 gitaly1 -docker rm gitlab-gitaly-ha praefect postgres gitaly3 gitaly2 gitaly1 +docker stop gitlab-gitaly-cluster praefect postgres gitaly3 gitaly2 gitaly1 +docker rm gitlab-gitaly-cluster praefect postgres gitaly3 gitaly2 gitaly1 ``` ## Guide to run and debug Monitor tests @@ -177,7 +177,7 @@ The following includes more information on the command: At the moment of this writing, there are two specs which run monitor tests: --`qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb` - has the specs of features in GitLab Core +-`qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb` - has the specs of features in GitLab Free -`qa/specs/features/ee/browser_ui/8_monitor/all_monitor_features_spec.rb` - has the specs of features for paid GitLab (Enterprise Edition) ### How to debug @@ -408,15 +408,15 @@ Geo requires an EE license. To visit the Geo sites in your browser, you need a r Tests that are tagged with `:ldap_tls` and `:ldap_no_tls` meta are orchestrated tests where the sign-in happens via LDAP. -These tests spin up a Docker container [(osixia/openldap)](https://hub.docker.com/r/osixia/openldap) running an instance of [OpenLDAP](https://www.openldap.org/). -The container uses fixtures [checked into the GitLab-QA repo](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/fixtures/ldap) to create +These tests spin up a Docker container [(`osixia/openldap`)](https://hub.docker.com/r/osixia/openldap) running an instance of [OpenLDAP](https://www.openldap.org/). +The container uses fixtures [checked into the GitLab-QA repository](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/fixtures/ldap) to create base data such as users and groups including the admin group. The password for [all users](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/9ffb9ad3be847a9054967d792d6772a74220fb42/fixtures/ldap/2_add_users.ldif) including [the `tanuki` user](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/9ffb9ad3be847a9054967d792d6772a74220fb42/fixtures/ldap/tanuki.ldif) is `password`. A GitLab instance is also created in a Docker container based on our [General LDAP setup](../../../administration/auth/ldap/index.md#general-ldap-setup) documentation. -Tests that are tagged `:ldap_tls` enable TLS on GitLab using the certificate [checked into the GitLab-QA repo](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/tls_certificates/gitlab). +Tests that are tagged `:ldap_tls` enable TLS on GitLab using the certificate [checked into the GitLab-QA repository](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/tls_certificates/gitlab). -The certificate was generated with openssl using this command: +The certificate was generated with OpenSSL using this command: ```shell openssl req -x509 -newkey rsa:4096 -keyout gitlab.test.key -out gitlab.test.crt -days 3650 -nodes -subj "/C=US/ST=CA/L=San Francisco/O=GitLab/OU=Org/CN=gitlab.test" @@ -432,7 +432,7 @@ To run the LDAP tests on your local with TLS enabled, follow these steps: `127.0.0.1 gitlab.test` - You can then run tests against GitLab in a Docker container on `https://gitlab.test`. Please note that the TLS certificate [checked into the GitLab-QA repo](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/tls_certificates/gitlab) is configured for this domain. + You can then run tests against GitLab in a Docker container on `https://gitlab.test`. Please note that the TLS certificate [checked into the GitLab-QA repository](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/tls_certificates/gitlab) is configured for this domain. 1. Run the OpenLDAP container with TLS enabled. Change the path to [`gitlab-qa/fixtures/ldap`](https://gitlab.com/gitlab-org/gitlab-qa/-/tree/9ffb9ad3be847a9054967d792d6772a74220fb42/fixtures/ldap) directory to your local checkout path: ```shell diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md index 94bc80abcdb..73fce3a38d7 100644 --- a/doc/development/testing_guide/frontend_testing.md +++ b/doc/development/testing_guide/frontend_testing.md @@ -31,7 +31,7 @@ Jest tests can be found in `/spec/frontend` and `/ee/spec/frontend` in EE. ## Karma test suite While GitLab has switched over to [Jest](https://jestjs.io), Karma tests still exist in our -application because some of our specs require a browser and can't be easiliy migrated to Jest. +application because some of our specs require a browser and can't be easily migrated to Jest. Those specs intend to eventually drop Karma in favor of either Jest or RSpec. You can track this migration in the [related epic](https://gitlab.com/groups/gitlab-org/-/epics/4900). @@ -258,7 +258,7 @@ it('exists', () => { ### Naming unit tests When writing describe test blocks to test specific functions/methods, -please use the method name as the describe block name. +use the method name as the describe block name. **Bad**: @@ -439,7 +439,7 @@ it('waits for an Ajax call', done => { }); ``` -If you are not able to register handlers to the `Promise`, for example because it is executed in a synchronous Vue life cycle hook, please take a look at the [waitFor](#wait-until-axios-requests-finish) helpers or you can flush all pending `Promise`s: +If you are not able to register handlers to the `Promise`, for example because it is executed in a synchronous Vue life cycle hook, take a look at the [waitFor](#wait-until-axios-requests-finish) helpers or you can flush all pending `Promise`s: **in Jest:** @@ -548,8 +548,12 @@ In order to ensure that a clean wrapper object and DOM are being used in each te }); ``` +<!-- vale gitlab.Spelling = NO --> + See also the [Vue Test Utils documentation on `destroy`](https://vue-test-utils.vuejs.org/api/wrapper/#destroy). +<!-- vale gitlab.Spelling = YES --> + ### Jest best practices > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34209) in GitLab 13.2. @@ -646,20 +650,46 @@ The latter is useful when you have `setInterval` in the code. **Remember:** our Non-determinism is the breeding ground for flaky and brittle specs. Such specs end up breaking the CI pipeline, interrupting the work flow of other contributors. -1. Make sure your test subject's collaborators (e.g., axios, apollo, lodash helpers) and test environment (e.g., Date) behave consistently across systems and over time. +1. Make sure your test subject's collaborators (e.g., Axios, apollo, Lodash helpers) and test environment (e.g., Date) behave consistently across systems and over time. 1. Make sure tests are focused and not doing "extra work" (e.g., needlessly creating the test subject more than once in an individual test) ### Faking `Date` for determinism -Consider using `useFakeDate` to ensure a consistent value is returned with every `new Date()` or `Date.now()`. +`Date` is faked by default in our Jest environment. This means every call to `Date()` or `Date.now()` returns a fixed deterministic value. + +If you really need to change the default fake date, you can call `useFakeDate` within any `describe` block, and +the date will be replaced for that specs within that `describe` context only: ```javascript import { useFakeDate } from 'helpers/fake_date'; describe('cool/component', () => { - useFakeDate(); + // Default fake `Date` + const TODAY = new Date(); - // ... + // NOTE: `useFakeDate` cannot be called during test execution (i.e. inside `it`, `beforeEach`, `beforeAll`, etc.). + describe("on Ada Lovelace's Birthday", () => { + useFakeDate(1815, 11, 10) + + it('Date is no longer default', () => { + expect(new Date()).not.toEqual(TODAY); + }); + }); + + it('Date is still default in this scope', () => { + expect(new Date()).toEqual(TODAY) + }); +}) +``` + +Similarly, if you really need to use the real `Date` class, then you can import and call `useRealDate` within any `describe` block: + +```javascript +import { useRealDate } from 'helpers/fake_date'; + +// NOTE: `useRealDate` cannot be called during test execution (i.e. inside `it`, `beforeEach`, `beforeAll`, etc.). +describe('with real date', () => { + useRealDate(); }); ``` @@ -702,10 +732,10 @@ unit testing by mocking out modules which cannot be easily consumed in our test Jest supports [manual module mocks](https://jestjs.io/docs/en/manual-mocks) by placing a mock in a `__mocks__/` directory next to the source module (e.g. `app/assets/javascripts/ide/__mocks__`). **Don't do this.** We want to keep all of our test-related code in one place (the `spec/` folder). -If a manual mock is needed for a `node_modules` package, please use the `spec/frontend/__mocks__` folder. Here's an example of +If a manual mock is needed for a `node_modules` package, use the `spec/frontend/__mocks__` folder. Here's an example of a [Jest mock for the package `monaco-editor`](https://gitlab.com/gitlab-org/gitlab/blob/b7f914cddec9fc5971238cdf12766e79fa1629d7/spec/frontend/__mocks__/monaco-editor/index.js#L1). -If a manual mock is needed for a CE module, please place it in `spec/frontend/mocks/ce`. +If a manual mock is needed for a CE module, place it in `spec/frontend/mocks/ce`. - Files in `spec/frontend/mocks/ce` mocks the corresponding CE module from `app/assets/javascripts`, mirroring the source module's path. - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` mocks the module `~/lib/utils/axios_utils`. @@ -728,11 +758,11 @@ If a manual mock is needed for a CE module, please place it in `spec/frontend/mo Global mocks introduce magic and technically can reduce test coverage. When mocking is deemed profitable: - Keep the mock short and focused. -- Please leave a top-level comment in the mock on why it is necessary. +- Leave a top-level comment in the mock on why it is necessary. ### Additional mocking techniques -Please consult the [official Jest docs](https://jestjs.io/docs/en/jest-object#mock-modules) for a full overview of the available mocking features. +Consult the [official Jest docs](https://jestjs.io/docs/en/jest-object#mock-modules) for a full overview of the available mocking features. ## Running Frontend Tests @@ -807,7 +837,7 @@ yarn karma -f 'spec/javascripts/ide/**/file_spec.js' ## Frontend test fixtures Frontend fixtures are files containing responses from backend controllers. These responses can be either HTML -generated from haml templates or JSON payloads. Frontend tests that rely on these responses are +generated from HAML templates or JSON payloads. Frontend tests that rely on these responses are often using fixtures to validate correct integration with the backend code. ### Generate fixtures @@ -865,7 +895,7 @@ end This will create a new fixture located at `tmp/tests/frontend/fixtures-ee/graphql/releases/queries/all_releases.query.graphql.json`. -Note that you will need to provide the paths to all fragments used by the query. +You will need to provide the paths to all fragments used by the query. `get_graphql_query_as_string` reads all of the provided file paths and returns the result as a single, concatenated string. @@ -929,7 +959,8 @@ it.each([ ); ``` -**Note**: only use template literal block if pretty print is **not** needed for spec output. For example, empty strings, nested objects etc. +NOTE: +Only use template literal block if pretty print is not needed for spec output. For example, empty strings, nested objects etc. For example, when testing the difference between an empty search string and a non-empty search string, the use of the array block syntax with the pretty print option would be preferred. That way the differences between an empty string e.g. `''` and a non-empty string e.g. `'search string'` would be visible in the spec output. Whereas with a template literal block, the empty string would be shown as a space, which could lead to a confusing developer experience @@ -1038,9 +1069,10 @@ import Subject from '~/feature/the_subject.vue'; import _Thing from '~/feature/path/to/thing.vue'; ``` -**PLEASE NOTE:** Do not simply disregard test timeouts. This could be a sign that there's +NOTE: +Do not disregard test timeouts. This could be a sign that there's actually a production problem. Use this opportunity to analyze the production webpack bundles and -chunks and confirm that there is not a production issue with the async imports. +chunks and confirm that there is not a production issue with the asynchronous imports. ## Overview of Frontend Testing Levels @@ -1063,7 +1095,7 @@ See also [Notes on testing Vue components](../fe_guide/vue.md#testing-vue-compon ## Test helpers Test helpers can be found in [`spec/frontend/__helpers__`](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/frontend/__helpers__). -If you introduce new helpers, please place them in that directory. +If you introduce new helpers, place them in that directory. ### Vuex Helper: `testAction` @@ -1090,9 +1122,13 @@ Check an example in [`spec/frontend/ide/stores/actions_spec.js`](https://gitlab. ### Wait until Axios requests finish +<!-- vale gitlab.Spelling = NO --> + The Axios Utils mock module located in `spec/frontend/mocks/ce/lib/utils/axios_utils.js` contains two helper methods for Jest tests that spawn HTTP requests. These are very useful if you don't have a handle to the request's Promise, for example when a Vue component does a request as part of its life cycle. +<!-- vale gitlab.Spelling = YES --> + - `waitFor(url, callback)`: Runs `callback` after a request to `url` finishes (either successfully or unsuccessfully). - `waitForAll(callback)`: Runs `callback` once all pending requests have finished. If no requests are pending, runs `callback` on the next tick. diff --git a/doc/development/testing_guide/index.md b/doc/development/testing_guide/index.md index 68326879dd0..c22a4e0b3ad 100644 --- a/doc/development/testing_guide/index.md +++ b/doc/development/testing_guide/index.md @@ -9,9 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w This document describes various guidelines and best practices for automated testing of the GitLab project. -It is meant to be an _extension_ of the [thoughtbot testing +It is meant to be an _extension_ of the [Thoughtbot testing style guide](https://github.com/thoughtbot/guides/tree/master/testing-rspec). If -this guide defines a rule that contradicts the thoughtbot guide, this guide +this guide defines a rule that contradicts the Thoughtbot guide, this guide takes precedence. Some guidelines may be repeated verbatim to stress their importance. diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md index a5294be40a9..f1c74f990cb 100644 --- a/doc/development/testing_guide/review_apps.md +++ b/doc/development/testing_guide/review_apps.md @@ -186,9 +186,9 @@ the GitLab handbook information for the [shared 1Password account](https://about ### Find my Review App slug 1. Open the `review-deploy` job. -1. Look for `Checking for previous deployment of review-*`. -1. For instance for `Checking for previous deployment of review-qa-raise-e-12chm0`, - your Review App slug would be `review-qa-raise-e-12chm0` in this case. +1. Look for `** Deploying review-*`. +1. For instance for `** Deploying review-1234-abc-defg... **`, + your Review App slug would be `review-1234-abc-defg` in this case. ### Run a Rails console @@ -357,7 +357,7 @@ using `v232`. For the record, the debugging steps to find out this issue were: -1. Switch kubectl context to review-apps-ce (we recommend using [kubectx](https://github.com/ahmetb/kubectx/)) +1. Switch kubectl context to `review-apps-ce` (we recommend using [`kubectx`](https://github.com/ahmetb/kubectx/)) 1. `kubectl get pods | grep dns` 1. `kubectl describe pod <pod name>` & confirm exact error message 1. Web search for exact error message, following rabbit hole to [a relevant Kubernetes bug report](https://github.com/kubernetes/kubernetes/issues/57345) diff --git a/doc/development/testing_guide/testing_migrations_guide.md b/doc/development/testing_guide/testing_migrations_guide.md index 31054d0ffb2..d54ca0d3c64 100644 --- a/doc/development/testing_guide/testing_migrations_guide.md +++ b/doc/development/testing_guide/testing_migrations_guide.md @@ -32,7 +32,7 @@ migrate the database **down** to the previous migration version. With this approach you can test a migration against a database schema. -An `after` hook migrates the database **up** and reinstitutes the latest +An `after` hook migrates the database **up** and restores the latest schema version, so that the process does not affect subsequent specs and ensures proper isolation. |