并行运行规范
5.0.0 及更高版本支持在 Node.js 中并行执行。在同时满足所有以下条件的情况下,可以并行运行 Jasmine 规范
- 使用
jasmine
软件包在 Node.js 中运行规范。 - 在支持随机化且未指定随机种子时,你的规范会始终通过。(这是 Jasmine 3.0 及更高版本中的默认配置。)
- 如果你有任何未包含在
describe
中的beforeAll
或afterAll
调用,则只使用它们来设置进程外状态(如数据库),而不是进程内状态(如全局变量)。 - 对
beforeEach
或afterEach
的任何调用都处于describe
中或位于辅助文件中。 - 如果你使用任何未随 Jasmine 提供的报告程序,则可以 对其进行更新,使其在并行模式下运行。
要使用并行模式
- 阅读以下限制和错误列表,并确保没有任何一项适用于你。特别是,请确保自己不必禁用随机化、指定随机种子或指定自定义顺序才能可靠地运行套件。
- 将
jasmine
依赖项设置为5.0.0
或更高版本。 - 将
--parallel=<n>
参数添加到jasmine
命令中,例如jasmine --parallel=4
在四个并行进程中运行规范。
理想的工作线程数量取决于规范的性质以及可用 CPU 核心的数量和类型。CPU 绑定套件通常在工作线程数量略小于核心数量时运行得最快。I/O 绑定套件可能会受益于较少的工作线程。
限制
以下限制仅适用于并行模式,不适用于正常的顺序执行模式。
- 无法禁用随机化,也无法设置随机种子。
- 不支持
fit
和fdescribe
。 - 在规范文件的顶层对
beforeEach
和afterEach
的调用不受支持。(在辅助文件中或describe
中对这些函数的调用仍然受到完全支持。) - 仅当在
describe
中时,才支持调用beforeAll
和afterAll
。如果您需要对超进程状态执行恰好一次的初始化,例如启动数据库或其他外部服务,请参阅下方描述的新全局设置/关闭 API。 - 不包含在 Jasmine 中的报告程序需要更新为以并行模式工作。有关更多信息,请参阅下方的报告程序部分。
- 不支持更改状态的
Env
方法,例如addReporter
、configure
等等。相反,请使用ParallelRunner
类的配置、CLI 参数或等效方法。 - 不支持
specFilter
核心配置属性,因为无法将函数发送给其他进程。相反,请使用--filter=
CLI 选项或将筛选器字符串作为第二个参数传递给ParallelRunner#execute
。
新增全局设置/关闭 API
Jasmine 5.0 提供了一个全新 API,用于恰好一次的全局设置和关闭。其目的是支持需要进行超进程设置的并行执行方案,无论使用多少个工作进程,只执行一次。它还可以在默认的顺序执行模式下使用。
如需使用全局设置/关闭 API,请将 globalSetup
和/或 globalTeardown
函数添加到您的 Jasmine 配置中,例如:
module.exports = {
spec_dir: "spec",
// ...
globalSetup() {
// ... your setup code here
}
globalTeardown() {
// ... your teardown code here
}
}
如果全局设置/关闭函数声明为 async
或以其他方式返回 Promise,Jasmine 将等到返回的 Promise 解决后才继续。不支持回调式异步。
不确定要使用哪个设置/关闭工具?
- 如果它需要在
describe
中的每个 spec 中运行,请在该describe
中使用beforeEach
/afterEach
。 - 如果它需要在整个套件中的每个 spec 中运行,请在帮手文件中使用
beforeEach
/afterEach
。(例如:添加应全局可用的自定义比较器。) - 如果它需要在
describe
中的所有 spec 中运行一次,请在该describe
中使用beforeAll
/afterAll
。 - 如果需要在整个套件的所有规范中运行一次并初始化外部状态,请使用
globalSetup
/globalTeardown
。顶级beforeAll
/afterAll
也可以用于此,但不能在并行模式下使用。(示例:启动外部服务或使数据库种子化。) - 如果需要在整个套件的所有规范中运行一次并初始化进程内状态,则不能使用并行模式。
需要注意的差异
- 某些类型的致命错误,如加载规范或帮助器文件时的错误,在顺序模式中将早于
jasmineStarted
报告器事件而发生,而在并行模式中将晚于该事件发生。 - 由于多个规范同时运行,在并行模式下可能很难或无法通过
console.log
进行调试。我们建议在调试时使用顺序模式或jasmine.debugLog
。 --fail-fast
CLI 选项和stopOnSpecFailure
配置设置支持尽力而为基础。执行将在第一时间故障发生后停止。
更新报告器以使其在并行模式中工作
并行模式对报告器施加了许多限制。由于一些最流行的第三方报告器需要进行一些更改才能在并行模式中工作,因此除非报告器声明兼容,否则 Jasmine 假定该报告器与并行模式不兼容。报告器可以通过显示值为 {parallel: true}
的 reporterCapabilities
属性来声明它与并行模式兼容。
事件顺序
需要注意的最大限制是事件在从工作器进程接收时按原样传递。这意味着无关的规范和套件的事件可以交织在一起。假定 specDone
事件与最近接收的 specStarted
事件属于同个规范,或者假定 suiteStarted
和 suiteDone
事件之间的所有事件都与该套件的孩子相关,这样的报告器在并行模式下不起作用。Jasmine 仅对并行模式中的事件排序做出以下保证:
jasmineStarted
在所有其他事件之前报告。jasmineDone
在所有其他事件之后报告。specStarted
在specDone
事件之前报告,该事件适用于同一个规范。- 对于同一套件,
suiteStarted
在suiteDone
事件前报告。 - 套件子集的所有事件将在套件的
suiteStarted
事件后和suiteDone
事件前进行报告。
在 Jasmine 4.6 及更高版本中,套件和规范报告事件都有一个 parentSuiteId
属性,它允许报告者识别规范或套件的父套件,而无需依赖于事件顺序。
并发事件分发
在顺序模式下,Jasmine 会在继续之前等待异步报告程序函数完成。而在并行模式下则不会等待。异步报告程序应该做好处理并发事件的准备或在内部对其进行排队。
API 的区别
此外,报告程序使用的许多 API 都不可用或受到限制
Env#topSuite
不可用。jasmineStarted
报告程序事件没有totalSpecsDefined
或order
字段。JasmineDone
报告程序事件没有order
字段。
请注意,上述内容仅适用于并行模式。在默认顺序模式下,Jasmine 5 与现有报告程序完全兼容。
以编程方式使用
您可以使用 ParallelRunner
类以编程方式并行运行规范。
const ParallelRunner = require('jasmine/parallel');
const runner = new ParallelRunner({numWorkers: 3});
runner.loadConfigFile('spec/support/jasmine.json');
runner.execute();
ParallelRunner
支持与 Jasmine
类相同的许多方法。有关详细信息,请参阅 API 参考文档。