如何在 javascript/node 中动态生成测试用例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22465431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:12:51  来源:igfitidea点击:

How can I dynamically generate test cases in javascript/node?

javascriptnode.jstesting

提问by Benj

The nose testing framework (for python) supports dynamically generating test cases at run-time(the following, from the documentation, results in five distinct test cases):

鼻子测试框架(用于python)支持在运行时动态生成测试用例(以下来自文档,导致五个不同的测试用例):

def test_evens():
    for i in range(0, 5):
        yield check_even, i, i*3

def check_even(n, nn):
    assert n % 2 == 0 or nn % 2 == 0

How can I achieve this result using javascript frameworks such as mocha or qunit? (I am not attached to any particular framework at this point.)

如何使用 mocha 或 qunit 等 javascript 框架实现此结果?(此时我不依附于任何特定框架。)

My use-case is writing a test runner to monitor several items on an external server. I would provide a list of resource URLs. Each test attempts to poll that resource and returns success or failure depending on what it finds. I have a prototype built in python (using nose) but would like to implement in node.js if I can. Eventually, this would be included in a CI setup.

我的用例是编写一个测试运行器来监控外部服务器上的几个项目。我会提供一个资源 URL 列表。每个测试都尝试轮询该资源并根据它找到的内容返回成功或失败。我有一个用 python 构建的原型(使用鼻子),但如果可以的话,我想在 node.js 中实现。最终,这将包含在 CI 设置中。

回答by Christiaan Westerbeek

Yes you can dynamically created test suites with cases using Mocha. I have installed mocha globally npm install -g mochaand I use should.

是的,您可以使用Mocha动态创建带有案例的测试套件。我已经在全球安装了 mochanpm install -g mocha并且我使用了should

var should = require('should');

var foo = 'bar';

['nl', 'fr', 'de'].forEach(function(arrElement) {
  describe(arrElement + ' suite', function() {
    it('This thing should behave like this', function(done) {
      foo.should.be.a.String();
      done();
    });
    it('That thing should behave like that', function(done) {
      foo.should.have.length(3);
      done();
    });
  });
});

回答by rob3c

If you want to dynamically create It()tests using data obtained asynchronously, you can (ab)use the before()hook with a placeholder It()test to ensure mocha waits until before()is run. Here's the example from my answer to a related question, for convenience:

如果您想It()使用异步获取的数据动态创建测试,您可以(ab)使用before()带有占位符It()测试的钩子来确保 mocha 等待直到before()运行。为方便起见,这是我对相关问题的回答中的示例:

before(function () {
    console.log('Let the abuse begin...');
    return promiseFn().
        then(function (testSuite) {
            describe('here are some dynamic It() tests', function () {
                testSuite.specs.forEach(function (spec) {
                    it(spec.description, function () {
                        var actualResult = runMyTest(spec);
                        assert.equal(actualResult, spec.expectedResult);
                    });
                });
            });
        });
});

it('This is a required placeholder to allow before() to work', function () {
    console.log('Mocha should not require this hack IMHO');
});

回答by Quanlong

With Mocha 1.21.4, you can create suite/test at runtime in following way.

使用 Mocha 1.21.4,您可以通过以下方式在运行时创建套件/测试。

require('chai').should()

Mocha = require 'mocha'
Test = Mocha.Test
Suite = Mocha.Suite


mocha = new Mocha
suite = Suite.create mocha.suite, 'I am a dynamic suite'
suite.addTest new Test 'I am a dynamic test', ->
  true.should.equal true

mocha.run () ->
  console.log("done")

See https://gist.github.com/cybertk/fff8992e12a7655157edfor more details

有关更多详细信息,请参阅https://gist.github.com/cybertk/fff8992e12a7655157ed

回答by Tom Spencer

It's worth noting that in addition to the accepted answer above, mocha's docs now include an example of how to achieve this. I've reproduced it below for posterity.

值得注意的是,除了上面接受的答案之外,mocha 的文档现在还包含一个如何实现这一点的示例。我在下面复制了它以供后代使用。

var assert = require('assert');

function add() {
  return Array.prototype.slice.call(arguments).reduce(function(prev, curr) {
    return prev + curr;
  }, 0);
}

describe('add()', function() {
  var tests = [
    {args: [1, 2],       expected: 3},
    {args: [1, 2, 3],    expected: 6},
    {args: [1, 2, 3, 4], expected: 10}
  ];

  tests.forEach(function(test) {
    it('correctly adds ' + test.args.length + ' args', function() {
      var res = add.apply(null, test.args);
      assert.equal(res, test.expected);
    });
  });
});

回答by Michael Yurin

Yep! Brilliant advice from Quanlong!

是的!来自全龙的绝妙建议!

Here is my example of dynamic test generation with Node's readlinemodule:

这是我使用 Node 的readline模块生成动态测试的示例:

const Mocha = require('mocha');
var Test = Mocha.Test;
var Suite = Mocha.Suite;

var mocha = new Mocha();
var suite = Suite.create(mocha.suite, 'My test suite with dynamic test cases');

lineReader
    .on('line', function (line) {
        suite.addTest(new Test(line, function () {
            return true;
        }));
    })
    .on('close', function () {
        mocha.run();
    });

回答by Jeff Lowery

I like @rob3c's answer, but tried to simplify it a bit:

我喜欢@rob3c 的回答,但试图简化一下:

describe("Master test suite", function () {
  before(async function () {
    const rows = await mySQLQuery();

    describe(`Testing ${rows.length} rows`, function () {
      rows.forEach(function (row, index) {
        it(`Test row ${index}`, async function() {
          console.log("your row assertions go here")
        });
      });
    });
  });


  it("stub", async function(){})  // this is important!
});

回答by Shannon Hochkins

You can accomplish this by updating the tests property manually after the response is returned from the async method:

您可以通过在从异步方法返回响应后手动更新测试属性来完成此操作:

describe(`sometest`, function() {
  let results = null
  before(async () => {
    results = await someAsyncMethod();
    results.forEach((result, index) => {
      // to hold on to the new dynamic tests
      const newTest = it(result.name || `test ${index}`, () => {
        // do something here in test
      });
      // update the test objects before the main tests run
      this.tests.push(newTest);
    });
  });

  it(`sometest`, () => {
    expect(results.length).toBeGreaterThan(2);
  });

});

This doesn't use dynamic describes etc, just updates the current describe block before the main tests run!

这不使用动态描述等,只是在主测试运行之前更新当前的描述块!