【问题标题】:Dynamically Running Mocha Tests动态运行 Mocha 测试
【发布时间】:2015-12-27 04:56:26
【问题描述】:

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

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,迭代似乎很好,并且似乎正在添加测试,所以我对操作流程很有信心,我只是无法得到任何执行或错误。

【问题讨论】:

    标签: node.js testing mocha.js


    【解决方案1】:

    测试您的测试系统并确保它能够处理通过和失败的测试以及引发的异常,这一点至关重要。 由于人们指望构建过程来警告他们错误,因此如果任何失败,您还必须将退出代码设置为非零。 下面是一个测试脚本(您必须使用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 测试的网络搜索中很突出,我将提供几个更有用的模板供人们复制。

    嵌入式执行:第一个直接添加测试,调用异步虚假网络调用并在.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)
      })
    }
    

    此代码处理传递和失败的数据,报告异常,并在出现错误时以非零状态退出。输出报告了所有预期的问题,另外还抱怨测试需要同样的时间(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 等待所有承诺解决或拒绝然后 创建测试以验证结果或报告异常。这比嵌入式执行要长几行,因为它必须:

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

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

    【讨论】:

      【解决方案2】:

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

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

      这是我正在运行的整个代码,改编自您的问题:

      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)
      

      【讨论】:

      • 现在我得到了输出,但只是0 passing (2ms)
      • 我已经添加了我正在运行的完整代码。有些事情我没有提到,比如导入 chai 以获取 expect,我认为这是切线的事情,但也许你也遇到了问题。
      • 是的,看起来像是我事先调用的进程的问题。似乎现在可以工作了,谢谢!
      猜你喜欢
      • 2020-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2023-04-05
      • 2018-01-11
      相关资源
      最近更新 更多