I have a service
class, which 50 other "services" extend. While each service has its own test, I would like to write a test suite for all of the services shared functionality (I have a method thing
which every service has to implement).
To test thing
, every service also has a function thingConfig
which returns an array of configurations thing
can run in. I would like to do the following:
describe('service', () => {
let configs;
before(async () => configs = await service.thingConfig())
configs.forEach(config => {
it(config.name + ' should run thing', () => {
thing = await service.thing(config);
expect(thing).to....
});
});
})
Is it possible to make this dynamic tests (forEach) based on asynchronous data?
In order to make it work, you have to make some dummy it case.
Look at the following example:
describe('Dummy spec', () => {
before(async () => {
const configs = await service.thingConfig();
describe('Generated spec', () => {
configs.forEach((config) => {
it(`Test for config: ${config}`, async () => {
const thing = await service.thing(config);
expect(thing).to....
});
});
});
});
it('Dummy test case, so before is executed', () => assert.strictEqual(1, 1));
});
Assuming that everything went well, you should see results in following form:
Dummy spec
√ Dummy test case, so before is executed
Generated spec
√ Test for config: test1
√ Test for config: test2
√ Test for config: test3
√ Test for config: test4
5 passing (3s)
Since this seems to be still an issue in mocha
(The delay flag breaks parallel mode and does not play well with TypeScript) I have been using a still hacky, but slightly more structured approach:
function asyncSuite(name: string, setupSuite: () => Promise<Suite>) {
suite(`Async dummy Suite for ${name}`, function () {
let suite: Suite;
suiteSetup(async () => (suite = await setupSuite()));
test(`Async tests for ${name} loaded`, async function () {
assert.ok(suite.suites.length || suite.tests.length);
});
});
}
Asynchronously added suites are never attached to their parents, as the suite tree is built synchronously by mocha. This approach makes that a bit clearer and forces you to create a suite for your asynchronously added data.
Additionally it tests for added tests and suites, preventing a silent fail when no tests are dynamically added. Usage is fairly simple, although you do have one extra indentation level:
asyncSuite('async tests', async function () {
const values = await new Promise<string[]>((r) => r(['abcd', 'efg', 'hijk']));
return suite('Asynchronous Test Suite', function () {
for (const value of values) {
test(`${value} is length 4`, () => {
assert.strictEqual(value.length, 4);
});
}
});
});
This will result in one dummy suite that is used to load the asynchronous dynamic tests in it's setup function and the actual test suite:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.