Atom Jasmine 3.x Test Runner
By default, Atom runs your tests with Jasmine 1.3 (for more information on testing packages in Atom, please
see the Atom Flight Manual).
Atom allows you to specify a custom test runner using the atomTestRunner
field in your package.json
, but
implementing a custom test runner is not straightforward. This module allows you to transition your specs to
Jasmine 3.x with minimal fuss.
Installation
$ npm install [--save-dev] atom-jasmine3-test-runner
Usage
Transition from Jasmine v1.3
There is legacy support for transitioning to Jasmine 3.x from 1.3.
By default any specs with a file name matching *-spec-v1.(js|coffee)
will be ran by the default Atom test runner after any new tests are ran.
Default Test Runner
If you want to use all the default options, simply pass the module name as the atomTestRunner
value in your package.json
:
{
"name": "my-package",
"atomTestRunner": "atom-jasmine3-test-runner"
}
Note that your package.json
may be cached by Atom's compile cache when running tests with Atom's GUI test runner, so
if adding or changing that field doesn't seem to work, try quitting and restarting Atom.
Writing TypeScript Tests
⚠ NOTE: If you use a custom runner that file (custom-runner.js
) must be a .js
file.
You must use atom-ts-transpiler
to transpile .ts
files to .js
on the fly in Atom.
npm i -D atom-ts-transpiler typescript
In your package.json
file you must add a "atomTranspilers"
property.
{
"name": "my-package",
"atomTranspilers": [
{
"transpiler": "atom-ts-transpiler",
"glob": "{!(node_modules)/**/,}*.ts?(x)",
"options": {...}
}
]
}
For more options see the atom-ts-transpiler
documentation
Programmatic Usage
If you'd like to perform more customization of your testing environment, you can create a custom runner while still utilizing
atom-jasmine3-test-runner for most of the heavy lifting. First, set atomTestRunner
to a relative path to a file:
{
"name": "my-package",
"atomTestRunner": "./spec/custom-runner"
}
Then export a test runner created via the atom-jasmine3-test-runner from ./spec/custom-runner.js
:
const { createRunner } = require('atom-jasmine3-test-runner');
const extraOptions = {
suffix: "-spec",
legacySuffix: "-spec-v1"
};
const optionalConfigurationFunction = function() {
require("some-jasmine-plugin");
beforeEach(function () {
jasmine.addMatchers({
toBeTheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything: function (util, customEqualityTesters) {
return {
compare: function (actual) {
let result = {};
result.pass = util.equals(actual, 42, customEqualityTesters);
const toBeOrNotToBe = (result.pass ? "not to be" : "to be");
result.message = `Expected ${actual} ${toBeOrNotToBe} the answer to the ultimate question of life, the universe, and everything.`;
return result;
}
};
}
});
});
}
module.exports = createRunner(extraOptions, optionalConfigurationFunction);
API
createRunner([options,] [callback])
Returns a test runner created with the given options
and callback
. Both parameters are optional. The returned value
can be exported from your atomTestRunner
script for Atom to consume.
Spec Helpers
This will include Atom's spec-helper.
The specHelper
option can be set to true
to enable the spec-helper or you can specify an object enabling only the parts of the spec-helper that you want.
Example:
const options = {
specHelper: {
atom: true,
attachToDom: true,
ci: true,
customMatchers: true,
jasmineFocused: true,
jasmineJson: true,
jasminePass: true,
jasmineTagged: true,
mockClock: true,
mockLocalStorage: true,
profile: true,
set: true,
unspy: true
}
}
These are the possible options for specHelper
Atom
atom: true
This will spy on atom.menu.sendToBrowserProcess
and add default config options:
atom.config.set("core.destroyEmptyPanes", false)
atom.config.set("editor.fontFamily", "Courier")
atom.config.set("editor.fontSize", 16)
atom.config.set("editor.autoIndent", false)
Attach To DOM
attachToDom: true
This will add the function jasmine.attachToDOM(element)
to allow you to easily attach elements to the DOM and it
takes care of removing the elements after every test so you don't need to worry about them messing with your other
tests. If you want an element to be attached to the DOM for multiple tests you can call jasmine.attachToDOM
in a
beforeEach
function.
CI
ci: true
This will throw an error if any focused tests are left when testing in a CI environment.
This will also set jasmine.DEFAULT_TIMEOUT_INTERVAL
to 1 minute in a CI environment.
:rotating_light: This won't do anything unless process.env.CI
is set :rotating_light:
env:
global:
- CI="true"
environment:
CI: "true"
machine:
environment:
CI: "true"
Custom Matchers
customMatchers: true
Uses jasmine2-atom-matchers
This will add the custom matchers from Atom:
- The
toBeInstanceOf
matcher is for the instanceof
operator - The
toHaveLength
matcher compares against the .length
property - The
toExistOnDisk
matcher checks if the file exists in the filesystem - The
toHaveFocus
matcher checks if the element currently has focus - The
toShow
matcher tests if the element is visible in the dom
This will also include the Atom custom version of jasmine-jquery
Jasmine Focused
jasmineFocused: true
Uses jasmine2-focused
This will include jasmine-focused (modified for Jasmine 3.x)
This includes the functions ffdescribe
, fffdescribe
, ffit
, and fffit
.
Jasmine JSON
jasmineJson: true
Uses jasmine2-json
This will include jasmine-json (modified for Jasmine 3.x)
This includes the matcher .toEqualJson(object)
and will give a detailed message on failure.
Jasmine Pass
jasminePass: true
Uses jasmine-pass
This will include a pass()
function similar to Jasmine's fail()
but opposite.
Jasmine Should Fail
jasmineShouldFail: true
Uses jasmine-should-fail
This will include the functions zdescribe
and zit
to allow you to tell jasmine that these tests should fail.
If these tests pass they will fail and if they fail they will pass but still output their messages as if they failed.
(really only useful for testing a reporter)
Jasmine Tagged
jasmineTagged: true
Uses jasmine2-tagged
This will include jasmine-tagged (modified for Jasmine 3.x)
This includes the functions jasmine.setIncludedTags([tags])
and jasmine.includeSpecsWithoutTags(bool)
to allow you to filter tests easily.
Mock Clock
mockClock: true
This will mock the setTimeout
and setInterval
functions, as well as a few others, so you can test a process that
happens on a timer with the advanceClock
function.
When this is enabled you will need to call jasmine.useRealClock()
if you want to use setTimeout
or setInterval
like usual.
This is similar to calling jasmine.clock().install()
Mock Local Storage
mockLocalStorage: true
Uses jasmine-local-storage
This includes the functions mockLocalStorage()
and unmockLocalStorage()
to allow you to mock localStorage.
You will have to call the mockLocalStorage()
function in-order to start mocking localStorage.
Profile
profile: true
This will include the functions measure(description, function)
and profile(description, function)
which will write
the time the function takes to console.log
Set
set: true
This will include the methods .jasmineToString()
and .isEqual(Set)
to the Set
prototype.
Unspy
unspy: true
Uses jasmine-unspy
This will include the function jasmine.unspy(object, method)
to allow you to restore the original function to a spy
Writing Tests
Jasmine documentation
describe('Testing', function () {
it('works', function () {
expect(42).toBeTheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything();
});
});
Credits
A huge thank you to @BinaryMuse for creating atom-mocha-test-runner
and giving me a place to start.