AVA测试框架中的断言机制详解
前言
AVA是一个现代化的JavaScript测试框架,它提供了一套简洁而强大的断言机制。断言是测试中最核心的部分,它决定了测试是否通过。本文将全面介绍AVA中的断言使用方法,帮助开发者更好地编写测试用例。
断言基础
在AVA中,断言是通过测试执行对象提供的。每个测试函数都会接收一个t
参数,这个参数包含了所有的断言方法。
test('基本断言示例', t => {
t.truthy('unicorn'); // 这是一个断言
});
断言特性
- 可传递性:断言方法可以赋值给变量或传递给其他函数
- 单次失败优先:如果一个测试中有多个断言失败,AVA只会显示第一个失败
- 类型保护:TypeScript用户可以使用部分断言作为类型保护
断言计划
断言计划是AVA的一个独特功能,它确保测试执行了预期数量的断言。
为什么需要断言计划
- 防止测试过早退出
- 避免在回调或循环中执行过多断言
- 确保至少有一个断言被执行(默认行为)
test('Promise解析测试', t => {
t.plan(1); // 计划执行1个断言
return Promise.resolve(3).then(n => {
t.is(n, 3); // 实际断言
});
});
常见陷阱
- 断言过多:实际断言数超过计划数会导致失败
- 异步问题:测试可能在异步断言执行前结束
断言修饰符
AVA提供了.skip
修饰符来跳过特定断言:
test('跳过断言示例', t => {
t.plan(2);
t.is.skip(foo(), 5); // 跳过的断言仍会计数
t.is(1, 1);
});
自定义断言
虽然AVA内置了丰富的断言,但也支持使用自定义断言库:
import assert from 'assert';
test('自定义断言示例', t => {
assert(true);
});
注意:使用自定义断言时需要关闭failWithoutAssertions
选项。
内置断言详解
基本断言
.pass()
- 直接通过.fail()
- 直接失败.assert(actual)
- 检查值是否为真
类型检查
.truthy(actual)
- 检查真值.falsy(actual)
- 检查假值.true(actual)
- 严格等于true.false(actual)
- 严格等于false
相等性检查
.is(actual, expected)
- 严格相等(Object.is).not(actual, expected)
- 严格不相等.deepEqual(actual, expected)
- 深度相等.notDeepEqual(actual, expected)
- 深度不相等.like(actual, selector)
- 选择性深度匹配
异常处理
.throws(fn, expectation)
- 同步函数应抛出异常.throwsAsync(thrower, expectation)
- 异步函数应抛出异常.notThrows(fn)
- 同步函数不应抛出异常.notThrowsAsync(nonThrower)
- 异步函数不应抛出异常
其他断言
.regex(contents, regex)
- 正则匹配.notRegex(contents, regex)
- 正则不匹配.snapshot(expected)
- 快照测试
高级特性:.try()
.try()
允许尝试执行断言而不影响测试结果:
test('尝试机制示例', async t => {
const attempt = await t.try(tt => {
tt.is(1, 2); // 这个断言会失败但不影响测试
});
if (attempt.passed) {
attempt.commit(); // 确认结果
} else {
attempt.discard(); // 丢弃结果
t.log(attempt.errors); // 记录错误
}
});
最佳实践
- 为异步测试合理使用断言计划
- 对不稳定测试使用
.try()
机制 - 优先使用内置断言以获得更好的错误信息
- 为复杂对象使用
.like()
而非全量比较 - 合理使用快照测试进行UI或配置测试
通过掌握AVA的这些断言特性,开发者可以编写出更健壮、更易维护的测试代码。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考