为什么Mocha不执行.then语句中的测试?



我正在使用Mocha/Chai制作一个Protractor测试套件(是的,我在Jasmine中遇到了同样的问题)。

因为应用程序是相当复杂的,我希望能够干燥地设置测试套件,允许我将操作链接到函数中。(例如,"登录,然后浏览到[parameterX],然后浏览到[parameter],然后期望第一个帖子标题是[parameterZ])。

但是当我把它们放在.then()语句中时,我似乎很难让Mocha运行测试。

下面是一小段代码片段,它显示了我所指的行为。

var chai = require('chai');
var cAP = require('chai-as-promised')
chai.use(cAP);
const expect = chai.expect;
const doTest = (x) => {
  describe('main', function() {
    it('should return foo', function(done) {
      expect(x).to.equal('foo')
    })
  })
}
const wait = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve(), 10000)
})
wait()
  .then(() => doTest('foo'))
/* results in
 *   0 passing (4ms)
 */

describeit块不能异步完成。如果你想在测试执行前等待10秒,你应该使用before块,它支持异步执行。你的before回调有一个参数,它是done回调。在这个block中,你可以等待10秒,然后调用done。所有后续的块都将等待,直到donebefore块中被调用。

describe('your tests', () => {
    before(done => {
        setTimeout(done, 10000)
    })
    it('should return foo', () => {
        expect(x).to.equal('foo')
    })
})

问题是您正在异步创建您的测试套件。默认情况下,Mocha不允许异步创建套件。我拿了你的代码,并做了以下更改:

  1. 从传递给it的回调中删除done参数,因为它是无用的。

  2. 我在doTest结束时增加了对run的呼叫

  3. 我用--delay选项调用Mocha: mocha --delay .

--delay选项将使Mocha等待构建测试套件。您可以通过调用run()来表示您已经完成了构建。以下是包含上述更改的完整代码:

var chai = require('chai');
var cAP = require('chai-as-promised')
chai.use(cAP);
const expect = chai.expect;
const doTest = (x) => {
  describe('main', function() {
    it('should return foo', function() {
      expect(x).to.equal('foo')
    })
  })
  run();
}
const wait = () => new Promise((resolve, reject) => {
  setTimeout(() => resolve(), 10000)
})
wait()
  .then(() => doTest('foo'))

chai-as-promise可以让它更简洁一些

/**
 * Modified by cool.blue on 26-Aug-16.
 */
'use strict';
var chai = require('chai');
var cAP = require('chai-as-promised');
chai.use(cAP);
const should = chai.should();
const wait5 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 5), 5000)
});
const wait10 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 10), 10000)
});
const doTest = (x, y, prep) => {
  describe('main', function() {
    this.timeout(15000);
    it('should return the right number for ' + x + ' and ' + y, function() {
      return prep(y).should.become(x)
    })
  })
};
[[17, 12, wait5], [15, 5, wait10], [15, 5, wait5]].forEach((listing) => doTest(...listing));

但是,要小心箭头函数:它们对语句和表达式的处理是不同的。

    it('should return the right number for ' + x + ' and ' + y,
      () => prep(y).should.become(x)
    )

完全不同
it('should return the right number for ' + x + ' and ' + y, () => {
  prep(y).should.become(x)
})

但与

完全相同
it('should return the right number for ' + x + ' and ' + y, () => {
  return prep(y).should.become(x)
})

箭头函数让我紧张,这就是为什么我更喜欢…

it('should return the right number for ' + x + ' and ' + y, function() {
  return prep(y).should.become(x)
})

我找不到确切的答案,但我找到了一些东西,可以满足我真正需要的东西,所以,这就是我所做的。

基本上,我可以将所有其他异步操作作为参数传递给测试函数,并且可以使用before块的done()回调来确保它们在正确的时间执行。

const wait5 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 5), 5000)
})
const wait10 = (something) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(something + 10), 10000)
})
const doTest = (x, y, prep) => {
  describe('main', function() {
    let z;
    before(function (done) {
      this.timeout(30000);
      prep(y).then((val) => {
        z = val;
        done();
      })
    })
    it('should return the right number for ' + x + ' and ' + y, () => {
      expect(x).to.equal(z)
    })
  })
}
[[17, 12, wait5], [15, 5, wait10], [15, 5, wait5]].forEach((listing) => doTest(...listing))

/* Result: 
  main
    √ should return the right number for 17 and 12
  main
    √ should return the right number for 15 and 5
  main
    1) should return the right number for 15 and 5

  2 passing (20s)
  1 failing
  1) main should return the right number for 15 and 5:
      AssertionError: expected 15 to equal 10
      + expected - actual
      -15
      +10
 */

最新更新