Basic Setup
If you have not already done so, you must create a new package first.
mkdir newpackage
cd newpackage
npm init
npm install --save-dev typescript tslint
Add tsconfig.json
The presented configuration is made so to get you started. You might want a more elaborated configuration for your own project.
The experimentalDecorators setting, however, is required as Testdeck makes heavy use of these.
1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"experimentalDecorators": true,
"lib": [ "es6" ]
}
}
Add tslint.json
The presented configuration is made so to get you started. You might want a more elaborated configuration for your own project.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {
"max-classes-per-file": false,
"max-line-length": false,
"no-empty": false,
"only-arrow-functions": false,
"no-console": false,
"object-literal-sort-keys": false,
"interface-name": false,
"ban-types": false,
"no-shadowed-variable": false,
"forin": false,
"member-ordering": false,
"deprecation": true,
"no-reference": false,
"trailing-comma": false
},
"rulesDirectory": []
}
Choose a Test Framework
Next, you need to choose which test framework you are going to use.
Testdeck supports Mocha, Jasmine and Jest.
With some limitations, you can always change the test framework later on. The most obvious limitations being the mocking framework and the assertion/expectation framework that you will use, which might or might not have a compatible API.
We have collected an overview of the available assertion/expectation frameworks and also some of the available mocking frameworks, so you can decide which route you will take in order to be able to migrate between test frameworks, provided that this is a valid use case for you.
@testdeck/mocha
# we only include @types/node here since we are using node's assert in the below example
npm install --save-dev @testdeck/mocha mocha @types/mocha ts-node @types/node
Edit package.json
{
"scripts": {
"test": "mocha --opts ./mocha.opts"
}
}
Add mocha.opts
--require source-map-support/register
--require ts-node/register
test/**/*test.ts
Add test/test.ts
1
2
3
4
5
6
7
8
9
10
11
12
import { suite, test } from '@testdeck/mocha';
import * as assert from 'assert';
@suite
class TestSuite {
@test
someTest() {
assert.ok(false);
}
}
Run tests
npm test
> mocha --opts ./mocha.opts
TestSuite
1) someTest
0 passing (24ms)
1 failing
1) TestSuite
someTest:
AssertionError [ERR_ASSERTION]: false == true
+ expected - actual
-false
+true
at TestSuite.someTest (test/test.ts:10:12)
at Context.someTest (node_modules/@testdeck/core/dist/index.js:158:39)
npm ERR! Test failed. See above for more details.
testdeck-mocha-seed
Alternatively, you can clone the existing testdeck-mocha-seed and start from there.
There you also find information on how to enable test coverage using nyc.
@testdeck/jasmine
npm install --save-dev @testdeck/jasmine jasmine @types/jasmine jasmine-ts jasmine-spec-reporter ts-node
Add jasmine.json
{
"spec_dir": "test",
"spec_files": [
"**/*[tT]est.ts"
],
"helpers": [
"helpers/**/*.ts"
],
"stopSpecOnExpectationFailure": false,
"random": false,
"reporters": [
{
"name": "jasmine-spec-reporter#SpecReporter",
"options": {
"displayStacktrace": "all"
}
}
]
}
Edit package.json
{
"scripts": {
"test": "jasmine-ts --config=./jasmine.json"
}
}
Add test/test.ts
1
2
3
4
5
6
7
8
9
10
11
import { suite, test } from '@testdeck/jasmine';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
Run tests
npm test
Jasmine started
TestSuite
✗ someTest
- Expected false to be true.
**************************************************
* Failures *
**************************************************
1) TestSuite someTest
- Expected false to be true.
Executed 1 of 1 spec (1 FAILED) in 0.017 sec.
testdeck-jasmine-seed
Alternatively, you can clone the existing jasmine-seed and start from there.
There you also find information on how to enable test coverage using nyc.
@testdeck/jest
npm install --save-dev @testdeck/jest jest @types/jest ts-jest typescript
Add jest.config.js
module.exports = {
rootDir: '.',
preset: 'ts-jest',
testMatch: ['<rootDir>/test/**/*test.ts'],
coverageThreshold: {
global: {
branches: 0,
functions: 0,
lines: 0,
statements: 0
}
}
};
Edit package.json
{
"scripts": {
"test": "jest"
}
}
Add test/test.ts
1
2
3
4
5
6
7
8
9
10
11
import { suite, test } from '@testdeck/jest';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
Run tests
npm test
> jest
FAIL test/test.ts
TestSuite
✕ someTest (8ms)
● TestSuite › someTest
expect(received).toBe(expected) // Object.is equality
Expected: true
Received: false
7 | someTest() {
8 |
> 9 | expect(false).toBe(true);
| ^
10 | }
11 | }
12 |
at TestSuite.someTest (test/test.ts:9:19)
at Object.someTest (node_modules/@testdeck/core/dist/index.js:158:39)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2.016s
Ran all test suites.
npm ERR! Test failed. See above for more details.
testdeck-jest-seed
Alternatively, you can clone the existing jest-seed and start from there.
There you also find information on how to enable test coverage using built-in jest functionality, which is based on nyc.
Assertion/Expectation Frameworks
Next, you might want to choose your assertion/expectation framework to actually implement your tests.
Here is a non exhaustive list of the available frameworks for you to choose from.
Chai.js
A highly recommended assertion/expectation framework which also supports expect/should in addition to the standard assert.
Setup
npm install --save-dev chai @types/chai
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { suite, test } from '@testdeck/mocha'; // might as well use jasmine/jest here
import * as chai from 'chai';
// let's have chai's should augmentations
chai.should();
@suite
class TestSuite {
@test
assertTest() {
chai.assert.isOk(false);
}
@test
expectTest() {
chai.expect(false).to.be.true;
}
@test
shouldTest() {
const val = false;
val.should.be.true;
}
}
Should.js
Should.js is a well established expectation framework.
Setup
npm install --save-dev should
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { suite, test } from '@testdeck/mocha'; // might as well use jasmine/jest here
import * as should from 'should';
@suite
class TestSuite {
@test
someTest() {
const var = false;
var.should.be.true();
}
}
Expect.js
Setup
npm install --save-dev expect.js @types/expect.js
Example Code
1
TODO
Expect (Jest)
While this is an integral part of the Jest test framework, it can be used as a stand alone package, too.
Setup
npm install --save-dev expect
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
import { suite, test } from '@testdeck/mocha';
import * as expect from 'expect';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
Expect (Jasmine)
While this is an integral part of the Jasmine test framework, it can be used as a stand alone package, too.
Setup
npm install --save-dev jasmine-expect
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
import { suite, test } from '@testdeck/mocha';
import * as expect from 'jasmine-expect';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
NodeJS assert
A simple, no fuss, assertion framework that is included with the standard NodeJS library.
Setup
This is part of the standard NodeJS library.
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
import { suite, test } from '@testdeck/mocha'; // might as well use jasmine/jest here
import * as assert from 'assert';
@suite
class TestSuite {
@test
someTest() {
assert.ok(false);
}
}
Jasmine built-in
For Jasmine, we recommend the built-in expectation framework.
Setup
This is an integral part of Jasmine.
Example Code
1
2
3
4
5
6
7
8
9
10
11
import { suite, test } from '@testdeck/jasmine';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
Jest built-in
For Jest, we recommend the built-in expectation framework.
Setup
This is an integral part of Jest.
Example Code
1
2
3
4
5
6
7
8
9
10
11
import { suite, test } from '@testdeck/jest';
@suite
class TestSuite {
@test
someTest() {
expect(false).toBe(true);
}
}
Mocking Frameworks
Sinon.JS
Sinon.JS is a popular mocking framework.
Setup
npm install --save-dev sinon @types/sinon sinon-chai @types/sinon-chai chai @types/chai
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { suite, test } from '@testdeck/mocha';
import * as chai from 'chai';
import * as sinon from 'sinon';
import * as sinonChai from 'sinon-chai';
chai.use(sinonChai);
class SUT {
private flags: {};
public setFlag(flag: string, value: boolean): void {
this.flags[flag] = value;
}
public getFlag(flag: string): boolean {
return this.flags[flag] || false;
}
}
@suite
class TestSuite {
private sut: SUT;
before() {
this.sut = new SUT();
}
@test
someTest() {
sinon.spy(this.sut, 'getFlag');
this.sut.setFlag('foo', true);
expect(this.sut.getFlag('foo')).toBe(true);
expect(this.sut.getFlag).to.have.been.calledWith('foo');
}
}
Jasmine built-in
Jasmine provides you with a built-in mocking facility.
Setup
This is an integral part of Jasmine.
Example Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { suite, test } from '@testdeck/jasmine';
class SUT {
private flags: {};
public setFlag(flag: string, value: boolean): void {
this.flags[flag] = value;
}
public getFlag(flag: string): boolean {
return this.flags[flag] || false;
}
}
@suite
class TestSuite {
private sut: SUT;
before() {
this.sut = new SUT();
}
@test
someTest() {
spyOn(this.sut, 'getFlag').and.returnValue(false);
expect(this.sut.getFlag('foo')).toBe(true);
}
}
Jest built-in
Jest, similarly to Jasmine, provides you with a built-in mocking facility.
And we will not go into length here on how that works.
See the official documentation here and here.
Setup
This is an integral part of Jest.
Example Code
See the example code in the official documentation.
Dependency Injection
- TypeDI
- testdeck offers support for TypeDI via its @testdeck/di-typedi package.