Edit in GitHubLog an issue

JavaScript unit testing with Jasmine

Commerce uses a custom Grunt task named spec to run Jasmine tests. The task collects the tests from <magento_root_dir>dev/tests/js/jasmine/tests and can be run for all tests, a theme, or a single test.

Prepare environment

Step 1. Install Node.js.

Step 2. Install grunt-cli.

Step 3. In <magento_root_dir>, create Gruntfile.js and copy Gruntfile.js.sample into it.

Step 4. In <magento_root_dir>, create package.json and copy package.json.sample into it.

Step 5. In <magento_root_dir>, install all dependencies:

Copied to your clipboard
npm install

Step 6. In <magento_root_dir>, generate static view files that are going to be tested

Copied to your clipboard
bin/magento setup:static-content:deploy -f

Note that normally you don't have permissions to <magento_root_dir>/app/code/, in fact the generated static view file is being tested.

For CentOS and Ubuntu users:

If the command fails with the error message:

Copied to your clipboard
/var/www/html/magento2ce/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory

Install fontconfig library:

  • CentOS:

    Copied to your clipboard
    yum install fontconfig
  • Ubuntu:

    Copied to your clipboard
    apt-get install fontconfig

Learn more in Deploy static view files.

Run tests

Gruntfile.js contains the test run task, so you can run all tests using the following command in the application root directory:

Copied to your clipboard
grunt spec:<THEME>

Example:

Copied to your clipboard
grunt spec:backend

or for the frontend area:

Copied to your clipboard
grunt spec:luma

You can also run a single test:

Copied to your clipboard
grunt spec:backend --file="/path/to/the/test.js"

or for the frontend area:

Copied to your clipboard
grunt spec:luma --file="/path/to/the/test.js"

Write a test

All tests are distributed through modules stored in <magento_root_dir>/dev/tests/js/jasmine/tests. Let's see how to write a test using an example of an existing test:

app/code/Magento/Ui/base/js/grid/columns/actions.test.js

which tests a JS module:

<magento_root_dir>/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js

in its static representations generated in Step 6 previously:

<magento_root_dir>/pub/static/<area>/<theme>/<localisation>/Magento_Ui/js/columns/actions.js.

Step 1. Create a new file with name <fileName>.test.js in an appropriate module directory.

For convenience, we can reflect the directory structure of a file to test.

A path to JS module that we want to cover with tests: app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js

A path to a test of the module: app/code/Magento/Ui/base/js/grid/columns/actions.test.js

In <magento_root_dir>/dev/tests/js/jasmine/tests create the test with appropriate path.

Step 2. Require a file that you want to test.

For our example we need to cover all static view files ending with Magento_Ui/js/grid/columns/actions.

Copied to your clipboard
define([
'Magento_Ui/js/grid/columns/actions'
], function (Actions) {
'use strict';
//Test code
//...
});

Step 3. Write your Jasmine test code.

A Jasmine test consists of main two parts:

  • describe blocks
  • it blocks

Both the describe and it functions contains two parameters:

  • a text string with description of what is going to be done
  • a function with block of code implementing described action

In describe you can use beforeEach and afterEach functions performing a preparation of what must be done before and after every it test followed.

Copied to your clipboard
define([
'underscore',
'Magento_Ui/js/grid/columns/actions'
], function (_, Actions) {
'use strict';
describe('ui/js/grid/columns/actions', function () {
var model,
action;
beforeEach(function () {
model = new Actions({
index: 'actions',
name: 'listing_action',
indexField: 'id',
dataScope: '',
rows: [{
identifier: 'row'
}]
});
action = {
index: 'delete',
hidden: true,
rowIndex: 0,
callback: function() {
return true;
}
};
});
it('Check addAction function', function () {
expect(model.addAction('delete', action)).toBe(model);
});
it('Check getAction function', function () {
var someAction = _.clone(action);
someAction.index = 'edit';
model.addAction('edit', someAction);
expect(model.getAction(0, 'edit')).toEqual(someAction);
});
it('Check getVisibleActions function', function () {
var someAction = _.clone(action);
someAction.hidden = false;
someAction.index= 'view';
model.addAction('delete', action);
model.addAction('view', someAction);
expect(model.getVisibleActions('0')).toEqual([someAction]);
});
it('Check updateActions function', function () {
expect(model.updateActions()).toEqual(model);
});
it('Check applyAction function', function () {
model.addAction('delete', action);
expect(model.applyAction('delete', 0)).toEqual(model);
});
it('Check isSingle and isMultiple function', function () {
var someAction = _.clone(action);
action.hidden = false;
model.addAction('delete', action);
expect(model.isSingle(0)).toBeTruthy();
someAction.hidden = false;
someAction.index = 'edit';
model.addAction('edit', someAction);
expect(model.isSingle(0)).toBeFalsy();
expect(model.isMultiple(0)).toBeTruthy();
});
it('Check isActionVisible function', function () {
expect(model.isActionVisible(action)).toBeFalsy();
action.hidden = false;
expect(model.isActionVisible(action)).toBeTruthy();
});
});
});

This topic doesn't provide Jasmine test writing methodology.

Learn more about testing with Jasmine.

Debug tests

Jasmine tests can be debugged in a browser using the following steps:

To keep the webserver running, set keepalive setting to true in the dev/tests/js/jasmine/spec_runner/settings.json file.

Launch the tests with the grunt spec:luma CLI command. Now the webserver should be started and waiting, _SpecRunner.html file should be generated in the project root.

Go to http://localhost:8000/_SpecRunner.html and use the developer console to debug the tests.

The array of the tests can be edited in the _SpecRunner.html file to include only necessary files.

Known issues and solutions

Error: Cannot find module '<module>'

Issue:

An error message appears:

Copied to your clipboard
Loading "Gruntfile.js" tasks...ERROR
>> Error: Cannot find module '<module>'
Warning: Task "spec" not found. Use --force to continue.

Solution:

  1. Make sure your Node.js version is up-to-date.
  2. Remove package.json, Gruntfile.js.
  3. Copy package.json, Gruntfile.js from package.json.sample, Gruntfile.js.sample.
  4. Delete the node_modules directory.
  5. Run npm install in your terminal.

Warning: Cannot read property 'pid' of undefined

Issue:

An error message appears:

Copied to your clipboard
Warning: Cannot read property 'pid' of undefined
Use --force to continue. Aborted due to warnings.

Solution:

Run in your terminal:

Copied to your clipboard
cd <magento_root>/node_modules/grunt-contrib-jasmine
Copied to your clipboard
npm install
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2024 Adobe. All rights reserved.