如果您查看qUnit源代碼,有兩種處理異常的機制。一個由config.notrycatch
設置控制,並將在try..catch
塊中包裝測試設置,執行和拆卸。這種方法對異步測試引發的異常沒有多大幫助,但qUnit並不是那裏的調用者。這就是爲什麼有一個額外的window.onerror
處理程序由Test.ignoreGlobalErrors
設置控制。默認情況下,這兩種設置都是false
,以便捕獲這兩種異常。事實上,下面的代碼(本質上和你一樣,但沒有具體的TinyMCE的零件)產生預期的結果對我來說:
test("foo", function()
{
stop();
function myfun(ed)
{
start();
ok(1, 'entered qunit again');
throw "bar";
}
setTimeout(myfun, 1000);
});
我第一次看到該消息的傳遞測試「再次輸入qunit」再失敗一條消息:「未捕獲的異常:酒吧」。至於爲什麼,這並不爲你工作,我可以看到以下選項:
- 你qUnit拷貝超過兩歲,以前qUnit issue 134是固定的,一個全球性的異常處理程序添加。
- 您的代碼正在更改
Test.ignoreGlobalErrors
設置(不太可能)。
- 有一個現有的
window.onerror
處理函數返回true
,因此告訴qUnit錯誤已被處理。我檢查了TinyMCE是否默認添加了一個,但它看起來不像。
- TinyMCE在調用它們時捕獲事件處理程序中的錯誤。這是多次回調打交道時做順理成章的事情,通常的做法是這樣的:
for (var i = 0; i < callbacks.length; i++)
{
try
{
callbacks[i]();
}
catch (e)
{
console.error(e);
}
}
通過重定向所有異常console.error
這可以確保例外仍然報告,而所有的回調會即使其中一個引發異常也會被調用。但是,由於異常處理jQuery不能再捕捉它。再一次,我檢查了TinyMCE是否實現了這種模式 - 它看起來不像它。
更新:原來有第五個選項,我沒有想到:異常是在幀內觸發的,並且qUnit沒有在其中設置全局錯誤處理程序(已經因爲跟蹤幀創建不是平凡的,任何時候都可以創建一個新的框架)。這應該是很容易固定,加入以下代碼框架:
window.onerror = function()
{
if (parent.onerror)
{
// Forward the call to the parent frame
return parent.onerror.apply(parent, arguments);
}
else
return false;
}
關於您的邊注:在console
對象不保證你在哪些消息出現在任何特定的順序。實際上,代碼console.log("foo");throw "bar";
也首先顯示異常,然後顯示日誌消息。這表明日誌消息排隊並處理延遲,可能是出於性能原因。但是,您需要查看Firefox的console
對象的實現情況,以確定它是否是實現細節。
感謝您的詳細解答。雖然'window.onerror'是一個函數,'window.frames [0] .onerror'和'window.frames [0] .frames [0] .onerror'爲null,這是測試發生的地方。看起來qUnit不是設計用iframes運行的嗎?我想我可以設置框架的恐怖成爲父母的恐怖,或者以某種方式稱它,我不確定是否有一個不太古怪的方式?你認爲qUnit會是推薦的方法嗎,不是Selenium或其他的? – NoBugs
@NoBugs:查看我的更新。至於使用qUnit - 爲什麼不呢?這當然是一種偏好,但硒通常使用起來更復雜。 –