2014-10-30 69 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; 
停止
相關問題