升級到 Jasmine 4.0
概述
摘要:更新到 3.99,並修復任何不建議使用的警告,然後再更新到 4.0。
我們認為大多數使用者都能輕鬆升級到 Jasmine 4.0。但是,它確實包含一些重大變更,有些人需要變更其程式碼才能升級。按照本指南中的步驟進行操作,將能大幅提升升級體驗的順暢度。
Jasmine 4.0 中的重大變更包括如何設定 Jasmine、自訂比對器和非對稱相等性測試器、更精確地偵測常見錯誤,以及系統需求的變更。您可以在 jasmine-core
和 jasmine
的版本說明中,找到重大變更的完整清單。
目錄
- 系統需求
- 使用 Jasmine 3.99 偵測相容性問題
- Ruby 和 Python 使用者遷移路徑
jasmine
套件公開介面- ES 模組支援
- 結束程式碼變更
- 如何處理 beforeAll 和 beforeEach 失敗
- 回報器介面變更
- 解決特定不建議使用警告的秘訣
系統需求
下列先前支援的環境不再支援
- Node <12.17
- Internet Explorer
- Firefox 68 和 78
- Safari 8-13
- PhantomJS
- Python
- Ruby
- Bower
儘管 Jasmine 4.0 仍可以在某些環境中執行,但我們不再針對這些環境進行測試,也不會嘗試在未來的 4.x 版本中維持與它們的相容性。奇數 Node 版本(13.x、15.x、17.x)不受支援,可能會運作,也可能不會。特別是,某些 13.x 版本對 ES/CommonJS 模組互通性的支援不完整,而且無法執行 Jasmine 4.0。
使用 Jasmine 3.99 偵測相容性問題
Jasmine 3.99 對大多數使用在 4.0 中已移除或以不相容方式變更的 API 的程式碼,發布不建議使用的警告。我們建議升級到 3.99 並修復所有不建議使用的警告,然後再升級到 4.0。您應該根據慣例,直接升級您依賴的 Jasmine 套件。如果您將 jasmine
NPM 套件、jasmine
Rubygem 或 jasmine
Python 套件升級到 3.99,您也將獲得 3.99 版本的 jasmine-core。
如果您正在使用 jasmine-browser-runner,只需將 jasmine-core
3.99 新增到您的依存關係就可以了。
Ruby 和 Python 使用者遷移路徑
3.99 是 Ruby 和 Python 的最終版本。我們建議大多數使用者改用 jasmine-browser-runner NPM 套件,它是 jasmine
Ruby gem 和 Python 套件的直接替換品。它可以在瀏覽器(包含無頭瀏覽器 Chrome 和 Saucelabs)中執行您的規格。它支援 Rails 應用程式,包括使用 Webpacker 的 Rails 應用程式,而這項功能從未受到 jasmine
gem 支援。
如果 jasmine-browser-runner
無法滿足您的需求,下列項目或許可以
- 在 Node.js 中執行規格的 jasmine NPM 套件。
- 不用任何其他工具,直接在瀏覽器中執行規格的 獨立發行版。
- 如果你只需要 Jasmine 資產,則使用 jasmine-core NPM 套件。這是與
jasmine-core
Ruby 寶石和 Python 套件完全對等的。
jasmine
套件公開介面
不像 jasmine-core
套件,jasmine
套件在 3.8 版本之前沒有經過說明的公共介面。從 4.0 開始,任何沒有包含在經過說明的公共介面中的部分都將被當作私人 API,並會隨時變更。如果你以程式編寫方式使用 jasmine
套件(例如,你具有執行 require('jasmine'
) 或 import('jasmine')
的程式碼),請根據 API 文件 檢查你的程式碼。
ES 模組支援
從版本 4 開始,jasmine
套件預設使用動態 import()
載入規格和其他檔案。這樣就能在不進行任何設定的情況下使用具有 .js
副檔名的 ES 模組。4.0.1 版本修復了載入具有 .jsx
或 .coffee
等非標準副檔名檔案的問題,所以如果你有這樣的檔案,請務必安裝至少該版本。
結束程式碼變更
在版本 4 之前,jasmine
命令幾乎在完全執行成功以外的所有情況下都會退出,且狀態為 1。版本 4 使用不同的退出碼表示不同的失敗類型。除非你的建置或 CI 系統特別檢查 1 退出碼(這非常不尋常),否則你不需要變更任何內容。任何將 0 視為成功,將其他所有狀況視為失敗的處理方式都依然可行。
變更 beforeAll
和 beforeEach
失敗的處理方式
Jasmine 4 以不同的方式處理 beforeAll
和 beforeEach
的失敗問題。這項變更可能會導致某些不尋常的設定和終止模式產生問題。只要你在建立資源的相同區套中終止資源,就不需要進行任何變更。
假設 beforeAll
函數的失敗原因並非預測失敗,Jasmine 4 會略過整個區套,但會執行與失敗的 beforeAll
定義在同一個區套中的任何 afterAll
函數。類似地,除了預測失敗以外的 beforeEach
失敗會導致任何後續 beforeEach
函數、問題中的規格,及在嵌套區套中定義的任何 afterEach
函數都會被略過。
// Unsafe. Test pollution can result because the afterEach won't always run.
describe('Outer suite', function() {
beforeEach(function() {
setSomeGlobalState();
possiblyFail();
});
describe('inner suite', function() {
it('does something', function() { /*...*/ });
// This afterEach function should be moved up to the outer suite.
afterEach(function() {
cleanUpTheGlobalState();
});
});
});
回報器介面變更
Jasmine 4.0 在 傳遞給報告器的 specDone 方法的物件 中新增了一個 debugLogs
欄位。如果規格呼叫 jasmine.debugLog 並且失敗,就會定義這個欄位。如果這個欄位存在,大多數報告器都應該要顯示它。
相較於前一版本,Jasmine 4.0 更可能會在 jasmineDone
事件中回報錯誤。未顯示這些錯誤在自訂回報器中是一項常見的臭蟲。你可以透過於頂層 (也就是非 describe
) 建立 afterAll
函式來檢查你的程式碼,它會引發例外狀況並確保你的回報器會顯示它。
解決特定不建議使用警告的秘訣
比對器中與自訂等號測試器相關的不建議事項
- "[name] 的比對器建置器接受自訂等號測試器,但此參數將不會傳遞給將來發布的版本中"
- "傳遞自訂等號測試器至 MatchersUtil#contains 已不建議使用。"。
- "傳遞自訂等號測試器至 MatchersUtil#equals 已不建議使用。"。
- "不相符的建立器應當被傳遞為 MatchersUtil#equals 的第三個引數,而非第四個引數。"。
於 3.6 之前,想要支援 自訂等號測試器 的 自訂比對器 必須接受一個自訂等號測試器陣列作為比對器建置器的第二個引數,並將其傳遞給諸如 MatchersUtil#equals
和 MatchersUtil#contains
等方法。自 3.6 開始,傳遞給比對器建置器的 MatchersUtil
執行個體已預先配置為包含目前的自訂等號測試器組,而比對器不需要提供它們。從 Jasmine 4.0 開始,自訂等號測試器既不會傳遞給比對器建置器,也不會接受為 MatchersUtil
方法的參數。若要將你的自訂比對器更新為新的樣式,只要從比對器建置器中移除額外參數,並停止將其傳遞給 MatchersUtil
方法即可。
之前
jasmine.addMatchers({
toContain42: function(matchersUtil, customEqualityTesters) {
return {
compare: function(actual, expected) {
return {
pass: matchersUtil.contains(actual, 42, customEqualityTesters)
};
}
};
}
});
之後
jasmine.addMatchers({
toContain42: function(matchersUtil) {
return {
compare: function(actual, expected) {
return {
pass: matchersUtil.contains(actual, 42)
};
}
};
}
});
提供給函式庫作者的注意事項
上述更新的形式僅相容於 Jasmine 3.6 及更新的版本。如果你想要維持與 Jasmine 較舊版本的相容性,你可以透過宣告比對器建置器僅使用一個引數,並使用 arguments
物件或 rest 參數語法 來存取自訂等號測試器陣列,進而避免不建議使用的警告。接著在傳遞其之前,檢查陣列上是否有 deprecated
屬性,該屬性會出現在 Jasmine 3.6 與更新的版本中
jasmine.addMatchers({
toContain42: function(matchersUtil, ...extraArgs) {
const customEqualityTesters =
extraArgs[0] && !extraArgs[0].deprecated ? extraArgs[0] : undefined;
return {
compare: function(actual, expected) {
return {
pass: matchersUtil.contains(actual, 42, customEqualityTesters)
};
}
};
}
});
"asymmetricMatch 的第二個引數現在是 MatchersUtil。將其用作自訂等號測試器陣列已不建議使用,且將於將來的版本中停止運作。"。
在 3.6 之前,想要支援 自訂相等性測試器 的 自訂非對稱相等性測試器 必須接受自訂相等性測試器的清單作為 asymmetricMatch
的第二個引數,並將它傳遞給 MatchersUtil#equals
和 MatchersUtil#contains
等方法。在 3.6 到 3.99 之間,第二個引數既是自訂相等性測試器的清單,也是 MatchersUtil
實例,該實例使用這些測試器進行事先設定。在 4.0 及之後,它只會是已妥善設定的 MatchersUtil
。若要解決不建議使用的警告,請直接使用提供的 MatchersUtil
之前
function somethingContaining42() {
return {
asymmetricMatch: function(other, customEqualityTesters) {
return jasmine.matchersUtil.contains(other, 42, customEqualityTesters);
}
};
}
之後
function somethingContaining42() {
return {
asymmetricMatch: function(other, matchersUtil) {
return matchersUtil.contains(other, 42);
}
};
}
提供給函式庫作者的注意事項
上述已更新的形式僅與 Jasmine 3.6 和後續版本相容。如果您想維持與 Jasmine 舊版本的相容性,可以檢查第二個引數是否是 MatchersUtil
(例如檢查是否有 equals
方法),並在它不是 MatchersUtil
時退回上述舊形式。
不再提供全球範圍使用的比對器工具的不建議使用通知
- 「jasmine.matchersUtil 已不建議使用,並會在日後版本的發行中移除。請改用傳遞給比對器工具工廠或非對稱相等性測試器之
asymmetricMatch
方法的實例。」 - 「jasmine.pp 已不建議使用,並會在日後版本的發行中移除。請改用傳遞給比對器工具工廠或非對稱相等性測試器之
asymmetricMatch
方法的 pp 方法。」
在 Jasmine 4.0 之前,有一個靜態的 MatchersUtil
實例可用於 jasmine.matchersUtil
,而一個靜態的 pretty 列印程式可用於 jasmine.pp
。由於這兩個目前都附帶特定於當前規格的設定,因此不再需要靜態實例。請勿使用 jasmine.matchersUtil
,請透過下列方式之一存取目前的 MatchersUtil
請勿使用 jasmine.pp
,請透過上述任一種方式存取 matchersUtil
,然後使用它的 pp 方法。
另請注意,如果一個物件有 jasmineToString
方法,pp
會被傳遞為第一個參數。
提供給函式庫作者的注意事項
matchersUtil
在 2.0 以後的版本傳遞給比對器工具工廠,在 2.6 以後的版本傳遞給非對稱相等性測試器。 matchersUtil#pp
在 3.6 引入,這也是第一個將 pretty 列印程式傳遞給 jasmineToString
的版本。如果您需要以與 3.6 之前的 Jasmine 版本相容的方式進行 pretty 列印,您可以檢查 MatchersUtil
實例或傳遞給 jasmineToString
的參數是否具有 pp
方法,然後在它不存在時退回到 jasmine.pp
。
混合使用兩種非同步形式的不建議使用通知
- 「非同步的 before/it/after 函式使用非同步關鍵字定義,但還採用 done 回呼。此種做法不受支援,且將在日後版本中停止運作。請移除 done 回呼(建議)或移除非同步關鍵字。」
- 「非同步性的 before/it/after 函式用了 done 回呼,但是也傳回了承諾。此作法不受支援,且在未來某個時間點會停止運作。請移除「已完成」的回呼(建議方法),或調整函式為不傳回承諾。」
Jasmine 從未支援過將多種非同步樣式合併的函式,它們也從來沒有過一致或明確的行為定義。只要在執行期間發現那樣的函式,Jasmine 4.0 便會發布規格失敗訊息。常見問答說明了解為何會做此變更,以及如何更新你的規格。
多次呼叫 done
導致的廢棄項目
- 「非同步函式已呼叫多次「已完成」回呼。此問題是規格、beforeAll、beforeEach、afterAll 或 afterEach 函式本身有錯誤所造成。在未來版本中,此情況將被視為錯誤。」
- 「頂層的 beforeAll 或 afterAll 函式已呼叫多次「已完成」回呼。此問題是 beforeAll 或 afterAll 函式本身有錯誤所造成。在未來版本中,此情況將被視為錯誤。」
Jasmine 先前容許多次呼叫 done
,但它掩蓋的錯誤已證明是常見的混淆來源。Jasmine 4 將在非同步函式呼叫 done
超過一次時回報錯誤。常見問答說明了解為何會做此變更,以及如何更新你的規格。
因重新呼叫 jasmine.clock().tick()
而導致的廢棄項目
在 4.0 之前,從 setTimeout
或 setInterval
處理函式內呼叫 jasmine.clock().tick()
會導致 Date
所顯示的目前時間往回推算。從 4.0 開始,即使重新呼叫 tick()
,目前時間也不會遞減。此情況可能會影響會從計時器處理函式內呼叫 tick()
,且同時也會注意目前時間的規格行為。
如果你發現問題的規格並沒有注意目前時間,或你打算在升級到 4.0 之後再檢查它們,你可以忽略這個警示。不過,我們建議調整問題的規格,以避免從計時器處理函式內呼叫 tick()
。
之前
it('makes a reentrant call to tick()', function() {
const foo = jasmine.createSpy('foo');
const bar = jasmine.createSpy('bar');
setTimeout(function() {
foo();
jasmine.clock().tick(9);
}, 1);
setTimeout(function() {
bar();
}, 10);
jasmine.clock().tick(1);
expect(foo).toHaveBeenCalled();
expect(bar).toHaveBeenCalled();
});
之後
it('does not make a reentrant call to tick()', function() {
const foo = jasmine.createSpy('foo');
const bar = jasmine.createSpy('bar');
setTimeout(function() {
foo();
}, 1);
setTimeout(function() {
bar();
}, 10);
jasmine.clock().tick(1);
expect(foo).toHaveBeenCalled();
jasmine.clock().tick(9);
expect(bar).toHaveBeenCalled();
});