declarative-test-structure-generator
The TypeScript typings are provided with the package.
This page is dedicated to the latest version. The documentation for v0 is available here.
declarative-test-structure-generator allows writing tests in an object definition style.
{
'Object syntax': {
tests: {
'sample test 1': {
test: () => {
expect(1 + 2).toEqual(3);
}
},
'skipped test': {
skip: true,
test: () => {
expect(5 + 8).toEqual(13);
}
}
}
}
}
As of version 1, the API has been refactored to be standalone, it no longer packs any specific test framework. The API needs to be mapped using pre-built or custom mappers (see below).
Motivations
The main motivation for this package was to isolate and reuse the test generation mechanism implemented in another of my projects. Mapping the test framework API to be object based allows to generate tests more simply (as well as reduce code required).
Disclaimer
This package has not been written as a new way to write tests.
Installation
npm install -D declarative-test-structure-generator
# or
yarn add -D declarative-test-structure-generator
Test framework API
As mentioned above, no test framework is provided with the package in order to ease the update and offer more flexibility. The structure definition syntax stays exactly the same between frameworks.
In order to facilitate the usage, the mapping for jasmine, jest and mocha is provided.
import {api, run, TestSuiteDefinition} from 'declarative-test-structure-generator';
run(definition, {api: api.jest});
// or
run(definition, {api: api.mocha});
// or
run(definition, {api: api.jasmine});
See examples for all 3 in the GitHub repository.
It is possible to provide a custom mapper to the api config by following the IApiMapper interface (see Jest example):
const jestApiExample = {
describe,
it,
before: beforeAll,
beforeEach,
after: afterAll,
afterEach,
only: {
describe: describe.only,
it: it.only
},
skip: {
describe: describe.skip,
it: it.skip
}
}
Examples
Syntax - Object / Array
import {api, run, TestSuiteDefinition} from 'declarative-test-structure-generator';
const definition: TestSuiteDefinition = {
'Object syntax': {
tests: {
'sample test 1': {
test: () => {
expect(1 + 2).toEqual(3);
}
},
'skipped test': {
skip: true,
test: () => {
expect(5 + 8).toEqual(13);
}
}
}
},
'Array syntax': {
tests: [
{
name: 'sample test 1',
test: () => {
expect(1 + 2).toEqual(3);
}
},
{
name: 'sample test 2',
test: () => {
expect(5 + 8).toEqual(13);
}
}
]
}
};
run(definition, {api: api.jest});
As illustrated above, both syntaxes are supported: object / array based. The provided definition (top-level) can either be an object or an array. Note the name property is required when using the array syntax.
Read the test suite definition and the test definition for additional details on the API.
Nesting test suites
The test suite definition allows for nested structure in both syntax:
{
'Object syntax': {
tests: {
'sample test 1': {
test: () => {
}
},
'Nested Test suite lvl 2': {
tests: {
'nested test': {
test: () => {
}
},
'Nested Test suite lvl 3': {
// each definition is independent
// you can set hooks, skip, only...
skip: true,
tests: {
'nested test': {
test: () => {
}
},
'nested test 2': {
test: () => {
}
}
}
}
}
}
}
}
}
Run only / skip
The properties skip and only allow to skip or only run a particular test.
It is a time saver when focusing / debugging a test. Read more extensively on the documentation of your test framework.
See usage in the test suite definition / test definition.
{
'sample test 1': {
only: true,
test: () => {
expect(1 + 2).toEqual(3);
}
},
'skipped test': {
skip: true,
test: () => {
expect(1 + 2).toEqual(3);
}
},
}
Test hooks
It is possible to run one or many functions at different phase of the test.
The hook definition is as follow:
before: is called once, before all tests.beforeEach: is called before each test.after: is called once, after all tests.afterEach: is called after each test.
Multiple hooks of the same type are supported using an array. Each hook is called in the specified order.
Additionally, provided your test library supports it, the following features are supported:
- Set context in the
beforeorbeforeEachhook viathisand afunction() {}used for the hook. - Async hooks via:
- done callback
- return of Promise
run({
'Object syntax': {
before: function() {
this.definedValue = 'Bill'
},
beforeEach: [
() => {
// do something
},
(done) => {
// do something async
done();
},
() => {
// do something async
return somePromise;
}
],
after: () => {
},
afterEach: () => {
},
tests: {
'sample test 1': {
test: function() {
// illustrates value set in the context of the before hook
expect(sayHello(this.definedValue)).toEqual('Hello Bill');
}
}
}
}
})
Definitions
Test suite definition
The test suite definition accepts the following:
{
skip: {boolean}
only: {boolean}
before: {function | Array[function]}
beforeEach: {function | Array[function]}
after: {function | Array[function]}
afterEach: {function | Array[function]}
tests: {Array<TestSuiteDefinition | TestDefinition> | Object<string, TestSuiteDefinition | TestDefinition>}
}
tests accepts either tests suites or tests as an object or an array.
Refer to the examples:
Test definition
The test definition accepts the following:
{
skip: {boolean}
only: {boolean}
test: {function}
}
The name must be provided when using the array syntax.
test: test function.
Refer to the examples: