summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Greiling <mike@pixelcog.com>2019-07-17 17:17:37 -0500
committerMike Greiling <mike@pixelcog.com>2019-07-19 02:27:14 -0500
commitfaa17d526371a34325705b8de9594e4e9df03298 (patch)
tree80cdc2603cb0e1da0edcd9310a812b64b630a08e
parent25fa78e2f9205427274772ff620d59cc9162400c (diff)
downloadgitlab-ce-faa17d526371a34325705b8de9594e4e9df03298.tar.gz
Rename the karma:fixtures task
Introduces frontend:fixtures rake task to replace karma:fixtures and update documentation and CI scripts to match
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml2
-rw-r--r--doc/development/testing_guide/frontend_testing.md11
-rw-r--r--lib/tasks/frontend.rake21
-rw-r--r--lib/tasks/karma.rake11
-rw-r--r--spec/frontend/helpers/fixtures.js2
5 files changed, 32 insertions, 15 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 22999a9d6b4..7695ce453ba 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -182,7 +182,7 @@ jest:
script:
- scripts/gitaly-test-spawn
- date
- - bundle exec rake karma:fixtures
+ - bundle exec rake frontend:fixtures
- date
- yarn jest --ci --coverage
artifacts:
diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md
index c909745b1ab..f16037e9e0a 100644
--- a/doc/development/testing_guide/frontend_testing.md
+++ b/doc/development/testing_guide/frontend_testing.md
@@ -80,18 +80,20 @@ describe('Component', () => {
Remember that the performance of each test depends on the environment.
### Manual module mocks
+
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. **Don't do this.** We want to keep all of our test-related code in one place (the `spec/` folder), and the logic that Jest uses to apply mocks from `__mocks__/` is rather inconsistent.
Instead, our test runner detects manual mocks from `spec/frontend/mocks/`. Any mock placed here is automatically picked up and injected whenever you import its source module.
- Files in `spec/frontend/mocks/ce` will mock the corresponding CE module from `app/assets/javascripts`, mirroring the source module's path.
- - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` will mock the module `~/lib/utils/axios_utils`.
+ - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` will mock the module `~/lib/utils/axios_utils`.
- Files in `spec/frontend/mocks/node` will mock NPM packages of the same name or path.
- We don't support mocking EE modules yet.
If a mock is found for which a source module doesn't exist, the test suite will fail. 'Virtual' mocks, or mocks that don't have a 1-to-1 association with a source module, are not supported yet.
#### Writing a mock
+
Create a JS module in the appropriate place in `spec/frontend/mocks/`. That's it. It will automatically mock its source package in all tests.
Make sure that your mock's export has the same format as the mocked module. So, if you're mocking a CommonJS module, you'll need to use `module.exports` instead of the ES6 `export`.
@@ -99,14 +101,15 @@ Make sure that your mock's export has the same format as the mocked module. So,
It might be useful for a mock to expose a property that indicates if the mock was loaded. This way, tests can assert the presence of a mock without calling any logic and causing side-effects. The `~/lib/utils/axios_utils` module mock has such a property, `isMock`, that is `true` in the mock and undefined in the original class. Jest's mock functions also have a `mock` property that you can test.
#### Bypassing mocks
+
If you ever need to import the original module in your tests, use [`jest.requireActual()`](https://jestjs.io/docs/en/jest-object#jestrequireactualmodulename) (or `jest.requireActual().default` for the default export). The `jest.mock()` and `jest.unmock()` won't have an effect on modules that have a manual mock, because mocks are imported and cached before any tests are run.
#### Keep mocks light
+
Global mocks introduce magic and can affect how modules are imported in your tests. Try to keep them as light as possible and dependency-free. A global mock should be useful for any unit test. For example, the `axios_utils` and `jquery` module mocks throw an error when an HTTP request is attempted, since this is useful behaviour in &gt;99% of tests.
When in doubt, construct mocks in your test file using [`jest.mock()`](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options), [`jest.spyOn()`](https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname), etc.
-
## Karma test suite
GitLab uses the [Karma][karma] test runner with [Jasmine] as its test
@@ -462,7 +465,7 @@ See this [section][vue-test].
For running the frontend tests, you need the following commands:
-- `rake karma:fixtures` (re-)generates [fixtures](#frontend-test-fixtures).
+- `rake frontend:fixtures` (re-)generates [fixtures](#frontend-test-fixtures).
- `yarn test` executes the tests.
As long as the fixtures don't change, `yarn test` is sufficient (and saves you some time).
@@ -548,7 +551,7 @@ HTML and JSON fixtures are generated from backend views and controllers using RS
For each fixture, the content of the `response` variable is stored in the output file.
This variable gets automagically set if the test is marked as `type: :request` or `type: :controller`.
-Fixtures are regenerated using the `bin/rake karma:fixtures` command but you can also generate them individually,
+Fixtures are regenerated using the `bin/rake frontend:fixtures` command but you can also generate them individually,
for example `bin/rspec spec/javascripts/fixtures/merge_requests.rb`.
When creating a new fixture, it often makes sense to take a look at the corresponding tests for the endpoint in `(ee/)spec/controllers/` or `(ee/)spec/requests/`.
diff --git a/lib/tasks/frontend.rake b/lib/tasks/frontend.rake
new file mode 100644
index 00000000000..e1f23bfa06e
--- /dev/null
+++ b/lib/tasks/frontend.rake
@@ -0,0 +1,21 @@
+unless Rails.env.production?
+ namespace :frontend do
+ desc 'GitLab | Frontend | Generate fixtures for JavaScript tests'
+ RSpec::Core::RakeTask.new(:fixtures, [:pattern]) do |t, args|
+ args.with_defaults(pattern: '{spec,ee/spec}/javascripts/fixtures/*.rb')
+ ENV['NO_KNAPSACK'] = 'true'
+ t.pattern = args[:pattern]
+ t.rspec_opts = '--format documentation'
+ end
+
+ desc 'GitLab | Frontend | Run JavaScript tests'
+ task tests: ['yarn:check'] do
+ sh "yarn test" do |ok, res|
+ abort('rake frontend:tests failed') unless ok
+ end
+ end
+ end
+
+ desc 'GitLab | Frontend | Shortcut for frontend:fixtures and frontend:tests'
+ task frontend: ['frontend:fixtures', 'frontend:tests']
+end
diff --git a/lib/tasks/karma.rake b/lib/tasks/karma.rake
index 2dc14183fa3..36590010406 100644
--- a/lib/tasks/karma.rake
+++ b/lib/tasks/karma.rake
@@ -1,15 +1,8 @@
unless Rails.env.production?
namespace :karma do
+ # alias exists for legacy reasons
desc 'GitLab | Karma | Generate fixtures for JavaScript tests'
- task fixtures: ['karma:rspec_fixtures']
-
- desc 'GitLab | Karma | Generate fixtures using RSpec'
- RSpec::Core::RakeTask.new(:rspec_fixtures, [:pattern]) do |t, args|
- args.with_defaults(pattern: '{spec,ee/spec}/javascripts/fixtures/*.rb')
- ENV['NO_KNAPSACK'] = 'true'
- t.pattern = args[:pattern]
- t.rspec_opts = '--format documentation'
- end
+ task fixtures: ['frontend:fixtures']
desc 'GitLab | Karma | Run JavaScript tests'
task tests: ['yarn:check'] do
diff --git a/spec/frontend/helpers/fixtures.js b/spec/frontend/helpers/fixtures.js
index b77bcd6266e..09d91e963fd 100644
--- a/spec/frontend/helpers/fixtures.js
+++ b/spec/frontend/helpers/fixtures.js
@@ -9,7 +9,7 @@ export function getFixture(relativePath) {
throw new ErrorWithStack(
`Fixture file ${relativePath} does not exist.
-Did you run bin/rake karma:fixtures?`,
+Did you run bin/rake frontend:fixtures?`,
getFixture,
);
}