简体   繁体   English

动态异步 mocha 测试

[英]Dynamic asynchronous mocha tests

I have a service class, which 50 other "services" extend.我有一个service类,它扩展了 50 个其他“服务”。 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).虽然每个服务都有它自己的测试,我想编写一个测试套件的所有服务的共享功能(我有一个方法thing ,其每一个服务必须实现)。

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:要测试thing ,每一个服务也有一个功能thingConfig返回配置数组thing可以运行在我想做到以下几点:

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?是否可以基于异步数据进行此动态测试(forEach)?

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:由于这似乎仍然是mocha一个问题(延迟标志破坏了并行模式并且不能很好地与 TypeScript 配合使用)我一直在使用一种仍然很笨拙但稍微结构化的方法:

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.异步添加的套件永远不会附加到它们的父级,因为套件树是由 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:这将产生一个虚拟套件,用于在其设置函数和实际测试套件中加载异步动态测试:

mocha 测试输出示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM