动态 运行 摩卡测试

Dynamically Running Mocha Tests

我正在尝试 运行 一系列动态测试。我有以下设置,但它似乎没有 运行 而且我没有收到任何错误:

import Mocha from 'mocha';
const Test = Mocha.Test;
const Suite = Mocha.Suite;
const mocha = new Mocha();
for (let s in tests) {
  let suite = Suite.create(mocha.suite, s);
  tests[s].forEach((test) => {
    console.log('add test', test.name)
    suite.addTest(new Test(test.name), () => {
      expect(1+1).to.equal(2);
    });
  });
}
mocha.run();

tests我运行宁长这样:

{ todo: 
  [ { name: 'POST /todos',
      should: 'create a new todo',
      method: 'POST',
      endpoint: '/todos',
      body: [Object] } ] }

(虽然此时我的测试只是试图检查一个基本的期望)

基于 console.logs 迭代似乎很好并且似乎正在添加测试,所以我对操作流程充满信心,我只是无法执行或出错。

您必须将测试函数传递给 Test 构造函数,而不是 suite.addTest。因此,更改您的代码以添加这样的测试:

suite.addTest(new Test(test.name, () => {
    expect(1+1).to.equal(2);
}));

这是我 运行ning 的全部代码,改编自您的问题:

import Mocha from 'mocha';
import { expect } from 'chai';
const Test = Mocha.Test;
const Suite = Mocha.Suite;
const mocha = new Mocha();

var tests = { todo:
  [ { name: 'POST /todos',
      should: 'create a new todo',
      method: 'POST',
      endpoint: '/todos',
      body: [Object] } ] };

for (let s in tests) {
  let suite = Suite.create(mocha.suite, s);
  tests[s].forEach((test) => {
      console.log('add test', test.name);
      suite.addTest(new Test(test.name, () => {
          expect(1+1).to.equal(2);
      }));
  });
}
mocha.run();

当我 运行 上面的 node_modules/.bin/babel-node test.es6 时,我得到输出:

  todo
    ✓ POST /todos


  1 passing (5ms)

测试您的测试系统并确保它处理通过和失败的测试以及抛出的异常是至关重要的。 由于人们指望构建过程向他们发出有关错误的警告,因此如果出现任何失败,您还必须将退出代码设置为 non-zero。 下面是一个测试脚本(您必须使用 node test.js 而不是 mocha test.js 来调用它),它会执行通过您的测试套件的所有路径:

const Mocha = require('mocha')
const expect = require('chai').expect
var testRunner = new Mocha()
var testSuite = Mocha.Suite.create(testRunner.suite, 'Dynamic tests')

var tests = [ // Define some tasks to add to test suite.
  { name: 'POST /todos', f: () => true }, //              Pass a test.
  { name: 'GET /nonos',  f: () => false }, //             Fail a test.
  { name: 'HEAD /hahas', f: () => { throw Error(0) } } // Throw an error.
]

tests.forEach(
  test =>
    // Create a test which value errors and caught exceptions.
    testSuite.addTest(new Mocha.Test(test.name, function () {
      expect(test.f()).to.be.true
    }))
)
var suiteRun = testRunner.run() //             Run the tests
process.on('exit', (code) => { //              and set exit code.
  process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors.
}) // Falling off end waits for Mocha events to finish.

鉴于这在异步 mocha 测试的网络搜索中很突出,我将提供一些更有用的模板供人们复制。

嵌入式执行: 第一个直接添加调用异步 faux-network 调用的测试,并在 .then:

中检查结果
const Mocha = require('mocha')
const expect = require('chai').expect
var testRunner = new Mocha()
var testSuite = Mocha.Suite.create(testRunner.suite, 'Network tests')

var tests = [ // Define some long async tasks.
  { name: 'POST /todos', pass: true, wait: 3500, exception: null },
  { name: 'GET /nonos', pass: false, wait: 2500, exception: null },
  { name: 'HEAD /hahas', pass: true, wait: 1500, exception: 'no route to host' }
]

tests.forEach(
  test =>
    // Create a test which value errors and caught exceptions.
    testSuite.addTest(new Mocha.Test(test.name, function () {
      this.timeout(test.wait + 100) // so we can set waits above 2000ms
      return asynchStuff(test).then(asyncResult => {
        expect(asyncResult.pass).to.be.true
      }) // No .catch() needed because Mocha.Test() handles them.
    }))
)
var suiteRun = testRunner.run() //             Run the tests
process.on('exit', (code) => { //              and set exit code.
  process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors.
}) // Falling off end waits for Mocha events to finish.

function asynchStuff (test) {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
//    console.log(test.name + ' on ' + test.endpoint + ': ' + test.wait + 'ms')
      if (test.exception)
        reject(Error(test.exception))
      resolve({name: test.name, pass: test.pass}) // only need name and pass
    }, test.wait)
  })
}

此代码处理传递和失败的数据、报告异常并在出现错误时以 non-zero 状态退出。输出报告了所有预期的问题,并且还抱怨测试花费了同样的时间(3.5 秒):

  Network tests
    ✓ POST /todos (3504ms)
    1) GET /nonos
    2) HEAD /hahas
  1 passing (8s)
  2 failing

  1) Network tests GET /nonos:
      AssertionError: expected false to be true
      + expected - actual    
      -false
      +true

  2) Network tests HEAD /hahas:
     Error: no route to host


延迟执行:这种方法在填充和启动 mocha 测试套件之前调用所有慢速任务:

const Mocha = require('mocha')
const expect = require('chai').expect
var testRunner = new Mocha()
var testSuite = Mocha.Suite.create(testRunner.suite, 'Network tests')

var tests = [ // Define some long async tasks.
  { name: 'POST /todos', pass: true, wait: 3500, exception: null },
  { name: 'GET /nonos', pass: false, wait: 2500, exception: null },
  { name: 'HEAD /hahas', pass: true, wait: 1500, exception: 'no route to host' }
]

Promise.all(tests.map( // Wait for all async operations to finish.
  test => asynchStuff(test)
    .catch(e => { // Resolve caught errors so Promise.all() finishes.
      return {name: test.name, caughtError: e}
    })
)).then(testList => // When all are done,
  testList.map( //     for each result,
    asyncResult => //  test value errors and exceptions.
      testSuite.addTest(new Mocha.Test(asyncResult.name, function () {
        if (asyncResult.caughtError) { // Check test object for caught errors
          throw asyncResult.caughtError
        }
        expect(asyncResult.pass).to.be.true
      }))
  )
).then(x => { //                                 When all tests are created,
  var suiteRun = testRunner.run() //             run the tests
  process.on('exit', (code) => { //              and set exit code.
    process.exit(suiteRun.stats.failures > 0) // Non-zero exit indicates errors.
  })
})

function asynchStuff (test) {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
//    console.log(test.name + ' on ' + test.endpoint + ': ' + test.wait + 'ms')
      if (test.exception)
        reject(Error(test.exception))
      resolve({name: test.name, pass: test.pass}) // only need name and pass
    }, test.wait)
  })
}

除了 mocha 没有抱怨测试速度慢,而是认为测试工具少于 10 毫秒外,输出是相同的。 Promise.all 等待所有承诺解决或拒绝 然后 创建测试以验证结果或报告异常。这比 Embedded execution 长几行,因为它必须:

  1. 解决异常,以便 Promise.all() 解决。
  2. 在最终 Promise.all().then()
  3. 中执行测试

描述人们如何选择使用哪种风格的评论可以指导其他人。分享你的智慧!