The Usage is documented in Covert's README.md file.
The Covert Project is a standalone Testrunner that runs in
node.js
version 12+
and uses ECMAScript imports
without transpilation to
guarantee identical behaviour when it comes to API tests or Integration tests.
- A Review is a set of tests, including preparation and cleanup helpers.
- Each Implementation in
/source/*.mjs
has a single Review located in/review/*.mjs
.
Covert is able to watch for filesystem changes (see Usage of watch
) and can
re-execute Review(s) when the Implementation has changed.
The covert.sh script builds the reference socks proxy
via make
and starts it in the background before the given set of Reviews
are executed.
As Covert also includes peer-to-peer tests for end-to-end network services, it requires the host machine to be reachable under at least two different IPs.
If the host machine has no internet connection, some network-related tests will fail, such as /stealth/connection/DNS, /stealth/connection/HTTPS, /stealth/connection/HTTP, or /stealth/client/Host.
As the only failsafe way to do this (without requiring two network cards or
WAN/LAN connections), there's the requirement to reach the local machine
via the IPs 127.0.0.1
, 127.0.0.2
and 127.0.0.3
.
MacOS
On MacOS it is necessary to create an alias for the loopback interface
before Covert itself can be run. The covert.sh
automatically creates an alias for above mentioned additional IPs on MacOS
and will ask for your sudo
password in order to do so.
Currently there's no way to simulate slower network connections as there's
no netem
nor tc
available on Darwin-based systems, so the --network
should not be used.
Multiple Example Reviews are available in these folders:
Codestyle Rules (Assumptions) of a Review:
- All Reviews (in
/review/*
) have to useES Modules
syntax. - All Source codes (in
/source/*
) have to useES Modules
syntax. - Reviews can have a single
before()
entry for preparation. - Reviews can have a single
after()
entry for cleanup. - Reviews can have multiple stateless
describe()
entries. - Reviews need to
export default
viafinish('library/namespace/Identifier')
to ensure ES Modules compatibility. assert()
calls have to be in a separate line.assert()
calls have to be branch-less, surroundingif/elseif/else
conditions are not allowed.
Exports of the Review Folder (/review/index.mjs
):
The index.mjs
of any review folder has to export the following properties as a default
export:
(Array) reviews[]
that contains all imported reviews.(Object) sources{}
that contains a source-to-review map that allows overriding which review have to reflect what implementation.
// Example index.mjs file
// imports of /review/*.mjs
import Foo from './Foo.mjs';
import Bar from './Bar.mjs';
import Doo from './network/Doo.mjs';
// Review ids are consistent with paths.
// Foo.id = 'my-project/Foo'
// Bar.id = 'my-project/Bar'
// Doo.id = 'my-project/network/Doo'
export default {
reviews: [
Foo,
Bar,
Doo
],
sources: {
// The Bar review has two implementations,
// one for node and one for the browser
'browser/Bar': 'Bar',
'node/Bar': 'Bar',
// The Bar review should test the following ES Module
// that is located at my-project/source/node/Bar.mjs
// (Note that polyfills can be tested this way)
'Bar': 'node/Bar',
// Qux does not need to be tested
'Qux': null
}
};
Example Review:
import { before, after, describe, finish } from '../../../covert/index.mjs';
import { Example } from '../../../project/source/namespace/Example.mjs';
before('prepare stuff', function(assert) {
this.example = new Example();
assert(this.example !== null);
this.example.on('event', () => {
assert(true);
});
});
describe('simple test', function(assert) {
assert(this.example !== null);
assert(this.example.method(), true);
this.example.async((response) => {
assert(response, { foo: 'bar' });
});
assert(this.example.url, 'https://example.com/index.html');
});
describe('debug test', function(assert, console) {
// This can be used with covert scan <Example> --debug=true
console.info('This is an info');
console.warn(this.example);
console.error('console is integrated');
console.blink('console is also sandboxed');
});
after('cleanup stuff', function(assert) {
this.example.on('destroy', () => {
assert(true);
});
this.example.destroy();
this.example = null;
});
// /project/source/namespace/Example.mjs is the Source Code (ES Module) implementation
// /project/review/namespace/Example.mjs is this Review
export default finish('my-project/namespace/Example');