升级至 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 来检测兼容性问题
对于大多数使用已在 4.0 中以不兼容方式移除或更改的 API 的代码,Jasmine 3.99 会发出弃用警告。我们建议先升级至 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 的最终版本。我们建议大多数用户迁移到 jasmine-browser-runner NPM 包,它是 jasmine
Ruby gem 和 Python 包的直接替代品。它在浏览器中运行您的规范,包括无头 Chrome 和 Saucelabs。它适用于 Rails 应用程序,包括那些使用 Webpacker 的应用程序,后者从未得到 jasmine
gem 的支持。
如果 jasmine-browser-runner
无法满足您的需要,以下内容之一可能满足
- jasmine NPM 包用于在 Node.js 中运行规范。
- 独立发行版用于在没有其他工具的情况下在浏览器中运行规范。
- jasmine-core NPM 包(如果您需要的只是 Jasmine 资产)。这是
jasmine-core
Ruby gem 和 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 将跳过除 any afterAll
函数(定义在 beforeAll
函数所在的相同套件中)之外的整个套件。同理,当 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
事件中报告错误。不显示这些错误是自定义报告程序中常见的错误。您可以通过在顶层创建一个 afterAll
函数(即不在 describe
中)来检查您自己,该函数引发异常,并确保您的报告程序显示它。
解决特定弃用警告的提示
与比较器中的自定义相等检验程序相关的弃用
- “[用于 [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 已弃用,将在将来的版本中删除。使用传递给匹配器工厂的 matchersUtil 的 pp 方法或非对称相等性测试人员的
asymmetricMatch
方法来代替。"
在 Jasmine 4.0 之前,有一个静态 MatchersUtil
实例可用作 jasmine.matchersUtil
,并且有一个静态漂亮打印机可用作 jasmine.pp
。因为这两个现在都承载了特定于当前规范的配置,所以不再有静态实例是有道理的。代替使用 jasmine.matchersUtil
,可以通过以下方式之一访问当前 MatchersUtil
不要使用 class="language-plaintext highlighter-rouge">jasmine.pp
,而是以上任意一种方式访问 class="language-plaintext highlighter-rouge">matchersUtil
,然后使用其 pp 方法。
另外,如果对象具有 class="language-plaintext highlighter-rouge">jasmineToString
方法,则会将 class="language-plaintext highlighter-rouge">pp
作为第一个参数传递。
致函库作者
自 2.0 以后的所有版本都给匹配器工厂提供了 class="language-plaintext highlighter-rouge">matchersUtil
,自 2.6 以后的所有版本都给非对称相等测试程序提供了 class="language-plaintext highlighter-rouge">matchersUtil
。class="language-plaintext highlighter-rouge">matchersUtil#pp
是在 3.6 中引入的,这也是向 class="language-plaintext highlighter-rouge">jasmineToString
传递漂亮打印程序的第一个版本。如果您需要以与低于 3.6 版本的 Jasmine 兼容的方式实现漂亮打印,那么可以在 class="language-plaintext highlighter-rouge">matchersUtil
实例或传递给 class="language-plaintext highlighter-rouge">jasmineToString
的参数上检查是否存在 class="language-plaintext highlighter-rouge">pp
方法,如果不存在,则回退到 class="language-plaintext highlighter-rouge">jasmine.pp
。
与混合使用两种形式的异步相关的弃用
- “异步的 before/it/after 函数使用 async 关键字定义,同时也使用 done 回调。这种用法不受支持,并且将来将停止工作。请移除 done 回调(推荐方法)或移除 async 关键字。”
- “异步的 before/it/after 函数使用 done 回调,但也返回一个 Promise。这种用法不受支持,并且将来将停止工作。请移除 done 回调(推荐方法)或更改函数,使其不返回 Promise。”
Jasmine 从不支持将多种形式的异步相结合的函数,并且它们的行为从未一致或明确。如果检测到此类函数,Jasmine 4.0 将发出规范失败。 常见问题解答对此更改的原因以及如何更新规范进行了讨论。
由于多次调用 class="language-plaintext highlighter-rouge">done
而导致的弃用
- “异步函数多次调用其 ‘done’ 回调。这是所涉规范、beforeAll、beforeEach、afterEach 或 afterAll 函数中的一个错误。将来会将此情况视为一个错误。”
- “顶级 beforeAll 或 afterAll 函数多次调用其 ‘done’ 回调。这是所涉 beforeAll 或 afterAll 函数中的一个错误。将来会将此情况视为一个错误。”
Jasmine 在历史上可以接受多个 done
调用,但这样做所掩盖的错误被证明是造成混淆的常见来源。每当异步函数调用 done
多次时,Jasmine 4 都会报告错误。常见问题讨论了进行此更改的原因以及如何更新规范。
不再推荐使用 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();
});