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

时间:2014-03-17 21:08:07

标签: javascript node.js testing

鼻子测试框架(对于python)支持dynamically generating test cases at run-time(以下,从文档中,导致五个不同的测试用例):

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

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

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

7 个答案:

答案 0 :(得分:31)

是的,您可以使用Mocha动态创建包含案例的测试套件。我已在全球范围内安装了mocha npm 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();
    });
  });
});

答案 1 :(得分:21)

如果要使用异步获取的数据动态创建It()测试,可以(ab)使用before()挂钩和占位符It()测试,以确保mocha等待{{1运行。以下是my answer to a related question中的示例,为方便起见:

before()

答案 2 :(得分:9)

值得注意的是,除了上面接受的答案,mocha's docs now include an example of how to achieve this。我在下面为后人再现了它。

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);
    });
  });
});

答案 3 :(得分:8)

使用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")

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

答案 4 :(得分:5)

是的!来自Quanlong的精彩建议!

以下是使用Node< strong> 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();
    });

答案 5 :(得分:0)

我喜欢@ 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!
});

答案 6 :(得分:0)

您可以通过从async方法返回响应后手动更新tests属性来完成此操作:

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);
  });

});

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