所以这是我试图用casperjs和mocha解决的问题。我试图在页面上测试元素的文本值,以查看它是否在... 5-10秒的时间内更新。我的想法是抓住值,将其推入数组,等待500毫秒并重复直到数组有20个项目。那是大约10秒钟。然后在数组上运行下划线/ lodash的_.uniq
函数,并测试数组长度为> 1
。
我遇到的问题是mocha没有等待这个完成,因为说明测试是成功/失败。我以为我可以增加摩卡的超时时间,但这没有任何区别。请参阅下面的代码。我已经评论了它的可读性。
it('has elements whose values update', function () {
// 20 seconds, which should be plenty of time
this.timeout(20000);
casper.then(function() {
// The test array
var values = [],
// So we can stop the intervals
intervalId;
function getValue () {
// Grab element's text value
var value = casper.evaluate(function () { return $('#element').text(); });
// Push in to our test array
values.push(value);
// 20 * 500ms == 10 seconds or 10000ms
// When set to 500ms, this block never runs. The test passes before it has a chance to
if (values.length === 20) {
// Stop it from checking the value any further
clearInterval(intervalId);
// Test to see we've had more than one unique value in the 10 seconds
expect(_.uniq(values).length).to.be.gt(1);
}
}
// Wait for the value on the page to populate
// It defaults to '-' when the page loads
casper.waitFor(function () {
return this.evaluate(function () {
return $('#element').text() !== '-';
});
// Start the check with a delay of 500ms between each check
}, function then() {
intervalId = setInterval(getValue, 500);
});
});
});
当间隔值设置为500ms时,在mocha进入下一个测试之前,我在values
中得到2-3个元素值。甚至更奇怪的是,当我确定测试通过时,他们在摩卡上的屏幕上打印console.log(values)
。原因是values.length
永远不会达到10,因此永远不会调用expect
调用。假设测试通过。以下是500毫秒间隔的测试输出:
Dashboard
✓ has elements whose values update (202ms)
Values: ["20,832,022"]
Values: ["20,832,022","20,832,372"]
Values: ["20,832,022","20,832,372","20,832,722"]
✓ has the page title of leads (41ms)
2 passing (11s)
即使没有20件物品也会通过。由于某处超时,它永远不会检查它。这是50ms间隔的输出:
Dashboard
✓ has elements whose values update (341ms)
Values: ["20,400,667"]
Values: ["20,400,667","20,400,718"]
Values: ["20,400,667","20,400,718","20,400,718"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871"]
Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871","20,400,922"]
Final Values: ["20,400,667","20,400,718","20,400,718","20,400,769","20,400,769","20,400,820","20,400,820","20,400,871","20,400,871","20,400,922"]
✓ has the page title of leads (41ms)
2 passing (8s)
我用50ms获得更多,但这只是测试的半秒。页面上的其他一些值需要更长的时间才能更新到此状态。
我已经尝试将done
回调传递给it
语句,但是mocha忽略它并且不等待它被调用。
这是工具的限制还是我使用它们错了?
我尝试使用以下方法完成回调。
it('has elements whose values update', function (done) {
和
expect(_.uniq(values).length).to.be.gt(1);
done();
我仍然忽略了我将测试标记为异步。在500ms时它仍然通过而没有进入if语句或完成调用。在50ms时会抛出此错误:
done() called multiple times
我正在使用mocha-casperjs。这会影响它吗?
答案 0 :(得分:2)
似乎mocha-casperjs没有使用默认的done
。它知道测试步骤已经完成,因为它使用了CasperJS'控制流。在您的情况下,您可以通过getValue
调用setInterval
来突破控制流程。
最好重构代码以使用getValue
的递归调用:
function getValue () {
// Grab element's text value
var value = this.evaluate(function () { return $('#element').text(); });
// Push in to our test array
values.push(value);
// 20 * 500ms == 10 seconds or 10000ms
// When set to 500ms, this block never runs. The test passes before it has a chance to
if (values.length === 20) {
// Test to see we've had more than one unique value in the 10 seconds
expect(_.uniq(values).length).to.be.gt(1);
} else {
this.wait(500, getValue);
}
}
// Wait for the value on the page to populate
// It defaults to '-' when the page loads
casper.waitFor(function () {
return this.evaluate(function () {
return $('#element').text() !== '-';
});
// Start the check with a delay of 500ms between each check
}, function then() {
this.wait(500, getValue);
});
这使getValue
成为一个步骤。
另一个没有太多重构的解决方案是让第二个waitFor
沿着破坏的控制流的一侧运行。这需要一个半全局变量someGlobalVariable
。也许intervalId
可以用于此,但最好在顶部使用someGlobalVariable = false;
。
intervalId = setInterval(getValue, 500);
this.waitFor(function check(){
return someGlobalVariable;
}, function then(){
// do something else
}, null, 20000);
让它停止
expect(_.uniq(values).length).to.be.gt(1);
someGlobalVariable = true;