2014-10-30 113 views
3

所以这里是我试图用casperjs和摩卡解决的问题。我试图在页面上测试一个元素的文本值,以查看它是否在...... 5-10秒的时间内更新。想法是我抓住价值,推入一个数组,等待500毫秒,并重复,直到数组有20个项目。那大约10秒。然后在阵列上运行下划线/ lodash的_.uniq函数,并测试数组长度为> 1摩卡不尊重超时或完成回调时运行CasperJS测试

我正在运行的问题是,摩卡没有等待完成,因为说明测试是成功/失败。我想我可以增加摩卡的超时时间,但这没有任何区别。请参阅下面的代码。我已经评论它的可读性。

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

对于设定为500毫秒的时间间隔值I获得到下一个测试之前摩卡移动在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声明,但摩卡忽略它,并不等待它被调用。

这是一个工具的限制还是我使用它们是错误的?

我已经尝试使用下面的方法完成回调。

it('has elements whose values update', function (done) { 

expect(_.uniq(values).length).to.be.gt(1); 
done(); 

它仍然忽略了我标志着试验,异步。在500ms时,它仍然通过,但没有进入if语句或完成的呼叫。在50毫秒它抛出这个错误:

done() called multiple times 

我使用mocha-casperjs。这会影响它吗?

回答

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; 
停止
相关问题