QUnit Decorators
Allow QUnit tests to be written and organized with JavaScript or TypeScript decorators. Inspired by mocha-typescript.
Setting this up in your project
npm install --save-dev qunit-decorators
or
yarn add -D qunit-decorators
Writing your tests
When using qunit-decorators, you’ll use classes organize modules, and methods for your tests
import { suite, test } from 'qunit-decorators';
@suite
class UserLoginTests {
@test
loginWithoutPassword(assert: Assert) {
let { result } = loginWithoutPassword();
assert.equal(result, 'ERROR', 'User receives an error');
}
foo() {}
}
In the example above your test module would get its name from the class (UserLoginTests
), and it would contain a test that gets its name from the method (loginWithoutPassword
). You may also pass an argument to these decorators, in order to provide your own names
see: QUnit.module and QUnit.test
import { suite, test } from 'qunit-decorators';
@suite('User authentication test suite')
class UserLoginTests {
@test('Missing password case errors as expected')
loginWithoutPassword(assert: Assert) {
let { result } = loginWithoutPassword();
assert.equal(result, 'ERROR', 'User receives an error');
}
}
Skipping & Focusing
Sometimes it's useful to temporarily focus on a subset of tests while writing new code. QUnit allows you to focus on a combination of modules and tests within modules.
see: QUnit.only
import { suite, test } from 'qunit-decorators';
@suite.only('Working on some new tests')
class MyNewTests { ... }
@suite
class ExistingFeatureTests {
@test.only('Fixing something else too')
buttonTest() { ... }
}
Alternatively, you may choose specific tests or modules to skip in a similar way
see: QUnit.skip
import { suite, test } from 'qunit-decorators';
@suite.skip('Things that take a long time')
class SlowTests { ... }
@suite
class ExistingFeatureTests {
@test.skip
buggyTest() { ... }
}
Particularly while in the middle of a code change, you'll sometimes have tests that won't pass because you haven't gotten to them yet. You may mark these tests with @test.todo
, and they'll pass as long as at least one assertion fails.
see: QUnit.todo
import { suite, test } from 'qunit-decorators';
@suite
class WIPBugFixes {
@test.todo("We'll get to this Soon™️")
somethingForTomorrow() {
assert.ok(false);
}
}
Module Hooks
When defining a QUnit suite, you have an opportunity to set up one or more hooks to customize code that runs before or after your tests.
see: QUnit.module
- before - Runs before the first test.
- beforeEach - Runs before each test.
- afterEach - Runs after each test.
- after - Runs after the last test.
There are a variety of ways you can provide functions for hooks, and qunit-decorators doesn't interfere with their normal capabilities and operation (i.e., if you return a promise from a hook, QUnit will wait for that promise to resolve before running other hooks or tests).
You may define hooks as static and member functions on the module's class
import { suite, test } from 'qunit-decorators';
import Pretender from 'pretender';
let server;
@suite('A better test module')
class BetterModule {
static before() {
server = new Pretender();
}
static after() {
server.shutdown();
}
beforeEach() { ... }
afterEach() { ... }
}
or pass the hooks passed into the @suite
decorator as an object
import { suite, test } from 'qunit-decorators';
import Pretender from 'pretender';
let server;
const myHooks = {
before() {
server = new Pretender();
},
after() {
server.shutdown();
}
}
@suite('A good test module', myHooks)
class GoodModule {
}
or pass in a callback that receives an object which may be used to register hooks
import { suite, test } from 'qunit-decorators';
import Pretender from 'pretender';
@suite('A better test module', hooks => {
let server;
hooks.before(() => {
server = new Pretender();
});
hooks.after(() => {
server.shutdown();
});
})
class BetterModule {
}
(c) 2018 LinkedIn