本指南将帮助您从 QUnit 1 升级到 QUnit 2。
概述
QUnit 2 版本只删除了旧方法。 “QUnit 2” 方法是在 QUnit 1.x 版本中引入的。如果您使用的是 QUnit 1.23,您可以在升级之前逐步迁移。
旧方法在 QUnit 2.0 中被删除,并被替换为抛出描述性错误的占位符方法,以简化迁移("Global 'test()' method is removed, use 'QUnit.test() instead")。QUnit 2.1 删除了这一层,而是会抛出像 "ReferenceError: test is not defined" 这样的原生错误。
| QUnit 1.x | QUnit 2.x |
|---|---|
module() |
QUnit.module() |
test() |
QUnit.test() |
asyncTest() |
QUnit.test() with assert.async() |
stop()/start() |
assert.async() |
expect() |
assert.expect() |
ok(), equal(), deepEqual(), … |
assert |
setup/teardown options |
beforeEach and afterEach hooks |
对于插件和其他集成
| QUnit 1.x | QUnit 2.x |
|---|---|
QUnit.log = …QUnit.begin = …… |
QUnit.log(…),QUnit.begin(…),… |
QUnit.push() |
assert.pushResult() |
QUnit.jsDump.parse() |
QUnit.dump.parse() |
更改
The qunit-migrate tool can automate the transition to QUnit 2.
- 删除全局函数
- 引入
assert.async - 重命名模块钩子
- 删除旧的回调属性
- 用
assert.pushResult替换QUnit.push - 删除
QUnit.init,没有替换 - 删除
QUnit.reset - 将
QUnit.jsDump重命名为QUnit.dump - 将
QUnit.test的expected数字参数替换掉 - 替换
assert.throws(Function, string, message)签名
删除全局函数
QUnit 2 不再使用全局函数。主要方法现在是 QUnit 接口的一部分,断言方法通过绑定到每个测试的新 assert 对象公开。
之前
module('example');
test('add', function () {
equal(add(2, 3), 5);
});
之后
QUnit.module('example');
QUnit.test('add', assert => {
assert.equal(add(2, 3), 5);
});
引入 assert.async()
使用 assert.async() 而不是 stop() 和 start() 函数。调用 assert.async() 返回一个 done 函数,该函数应在异步操作完成后调用。
类似地,如果您使用的是 asyncTest(),请使用带有 assert.async() 的常规 QUnit.test()。
之前
QUnit.test('navigates to new page', function () {
stop();
router.navigate(function (newPage) {
equal(newPage.id, 1);
start();
});
});
// Or
asyncTest('navigates to new page', function () {
router.navigate(function (newPage) {
equal(newPage.id, 1);
start();
});
});
之后
QUnit.test('navigates to new page', assert => {
const done = assert.async();
router.navigate(newPage => {
assert.equal(newPage.id, 1);
done();
});
});
重命名模块钩子
模块钩子 setup 和 teardown 已重命名为 beforeEach 和 afterEach。新名称首次出现在 QUnit 1.16 中,并在 QUnit 2.0 中删除。
之前
QUnit.module('router', {
setup: function () {
this.router = new Router();
},
teardown: function () {
this.router.destroy();
}
});
之后
QUnit.module('router', {
beforeEach: () => {
this.router = new Router();
},
afterEach: () => {
this.router.destroy();
}
});
从 QUnit 1.20 开始,您还可以使用 嵌套范围,这使得更轻松地共享变量并将测试与模块关联起来。
示例
QUnit.module('router', hooks => {
let router;
hooks.beforeEach(() => {
router = new Router();
});
hooks.afterEach(() => {
router.destroy();
});
QUnit.test('add', assert => {
assert.true(router.add('/about'));
});
});
删除旧的回调属性
QUnit 0.x 的早期 alpha 版本需要属性赋值来注册回调事件。在 QUnit 1.0 中,这些被弃用,转而使用更现代的事件注册方法。在 QUnit 2.0 中,使用赋值作为注册回调的方式被删除。
另请参阅 QUnit.on(),它从 QUnit 2.2 开始实现 js-reporters 规范。
之前
QUnit.log = function (results) {
console.log(results);
};
之后
QUnit.log(function (results) {
console.log(results);
});
这适用于所有报告回调,特别是:begin、done、log、moduleDone、moduleStart、testDone 和 testStart。
将 QUnit.push() 替换为 assert.pushResult()
要实现自定义断言,请将函数分配给 QUnit.assert,并在内部使用 this.pushResult() 而不是 QUnit.push。这允许断言直接与其测试上下文相关联,防止异步测试泄漏到其他测试中。
之前
QUnit.assert.mod2 = function (value, expected, message) {
const actual = value % 2;
QUnit.push(actual === expected, actual, expected, message);
};
之后
QUnit.assert.mod2 = function (value, expected, message) {
const actual = value % 2;
this.pushResult({ result: actual === expected, actual, expected, message });
};
删除 QUnit.init,没有替换
此方法用于重新初始化测试运行器。它不应该公开为公共方法,现在已移除,没有替代方案。如果您构建了需要使用 QUnit.init 的集成或运行器框架,请在我们的 聊天室 中联系我们,或在 问题跟踪器 中联系我们,以帮助找到替代方案。
删除 QUnit.reset
此方法访问了 QUnit 的内部夹具重置。现在已移除,没有替代方案。如果您的代码正在使用它,您可能需要将受影响的测试拆分为单独的测试。
之前
QUnit.test('currentPage', assert => {
router.refresh();
assert.equal(router.currentPage.id, 1);
QUnit.reset();
history.replaceState('/about');
router.refresh();
assert.equal(router.currentPage.id, 42);
});
之后
QUnit.test('currentPage default', assert => {
router.refresh();
assert.equal(router.currentPage.id, 1);
});
QUnit.test('currentPage after replaceState', assert => {
history.replaceState('/about');
router.refresh();
assert.equal(router.currentPage.id, 42);
});
将 QUnit.jsDump 重命名为 QUnit.dump
最初 jsDump 是一个独立的库,导入到 QUnit 中。它后来在库中进一步发展。为了反映这一点,该属性已重命名为 QUnit.dump.parse。这只会影响自定义报告程序代码,不会影响常规测试套件。
之前
QUnit.log(obj => {
const actual = QUnit.jsDump.parse(obj.actual);
const expected = QUnit.jsDump.parse(obj.expected);
sendMessage(obj.result, actual, expected);
});
之后
QUnit.log(obj => {
const actual = QUnit.dump.parse(obj.actual);
const expected = QUnit.dump.parse(obj.expected);
sendMessage(obj.result, actual, expected);
});
将 QUnit.test 的 expected 数字参数替换掉
用于指定预期断言数量的 QUnit.test 的可选 expected 参数已移除。请改用 assert.expect()。
之前
QUnit.test('addition', 1, assert => {
assert.equal(add(2, 3), 5);
});
之后
QUnit.test('addition', assert => {
assert.expect(1);
assert.equal(add(2, 3), 5);
});
替换 assert.throws(Function, string, message) 签名
接受错误字符串作为第二个参数的 assert.throws() 的签名已移除。这避免了与断言消息的歧义,因为两个参数都是可选的。
建议使用正则表达式或错误对象作为预期值。
例如,要测试以下代码
function add (a, b) {
if (a === undefined) {
throw new Error('This is an error');
}
}
之前
QUnit.test('add', assert => {
assert.throws(() => {
add();
}, 'This is an error', 'Fail if A is undefined');
});
之后
QUnit.test('add', assert => {
assert.throws(() => {
add();
}, /This is an error/, 'Fail if A is undefined');
});
// Or
QUnit.test('add', assert => {
assert.throws(() => {
add();
}, new Error('This is an error'), 'Fail if A is undefined');
});
有关支持签名的概述,请参阅 assert.throws()。
请注意,在两个参数签名 assert.throws(Function, string) 中,始终被解释为断言任何内容被抛出,字符串参数是断言消息。这将继续得到支持。