一、Jasmine 到底是啥?
一个「对话式测试工具」,核心就是:你告诉它 "应该发生什么",它去执行代码,然后告诉你 "对不对" 。
运行机制:
- 测试代码 :你写一段代码,描述 "某个函数调用后应该返回 10"
- 被测试的代码 :比如你写的
add(3,7)
这个函数 - Jasmine 引擎 :执行你的测试代码,对比 "预期结果" 和 "实际结果",最后告诉你通过没
最核心的 3 个概念:
describe
:给你的测试分组(比如 "计算器功能测试")it
:描述一个具体的测试点(比如 "1+1 应该等于 2")expect
:断言(你觉得结果应该是啥)
二、从零开始写第一个测试:加法函数
假设我们有个简单的加法函数,存放在 calculator.js
里:
css
// calculator.js
function add(a, b) {
return a + b;
}
现在用 Jasmine 测试它,步骤超简单:
1. 写测试代码(存成 calculator.spec.js
)
scss
// 第一步:给测试分组(比如"计算器的加法测试")
describe('计算器的加法功能', () => {
// 第二步:写具体的测试用例(比如"两个正数相加")
it('1加2应该等于3', () => {
// 第三步:调用被测试的函数,拿到实际结果
const result = add(1, 2);
// 第四步:断言"实际结果应该等于预期结果"
expect(result).toBe(3);
});
// 再写一个测试用例:负数相加
it('-1加-2应该等于-3', () => {
const result = add(-1, -2);
expect(result).toBe(-3);
});
});
2. 执行测试后会看到啥?
如果代码没问题,会显示:
计算器的加法功能
✓ 1加2应该等于3
✓ -1加-2应该等于-3
2 个测试通过
如果不小心把 add
函数写成了 a - b
,就会报错:
markdown
计算器的加法功能
✗ 1加2应该等于3
预期:3,实际:-1
✗ -1加-2应该等于-3
预期:-3,实际:1
2 个测试失败
三、常用断言:除了 toBe 还有这些
刚才用了 toBe
判断 "是否相等",Jasmine 还有很多常用的 "断言工具",比如:
断言方法 | 作用举例 |
---|---|
expect(a).toBe(b) |
判断 a 和 b 严格相等(===) |
expect(arr).toContain(2) |
判断数组里有 2 |
expect(str).toMatch(/hello/) |
判断字符串包含 hello |
expect(num).toBeGreaterThan(5) |
判断数字大于 5 |
示例:测试一个数组工具函数
scss
// 被测试的函数:判断数组是否包含偶数
function hasEvenNumber(arr) {
return arr.some(num => num % 2 === 0);
}
// 测试代码
describe('数组工具函数', () => {
it('包含偶数时应该返回true', () => {
const result = hasEvenNumber([1, 3, 4]);
expect(result).toBe(true); // 断言结果为true
});
it('不包含偶数时应该返回false', () => {
const result = hasEvenNumber([1, 3, 5]);
expect(result).toBe(false); // 断言结果为false
});
});
四、进阶一点:测试前准备,测试后清理
有时候测试需要 "准备工作"(比如创建一个测试数据),或者 "收尾工作"(比如清空数据),Jasmine 提供了两个函数:
-
beforeEach
:每个it
执行前自动运行(比如每次测试前都初始化一个空数组) -
afterEach
:每个it
执行后自动运行(比如每次测试后清空数组)
示例:测试一个购物车添加商品的功能
scss
// 被测试的购物车对象
const cart = {
items: [],
addItem(item) {
this.items.push(item);
},
getTotal() {
return this.items.length;
}
};
// 测试代码
describe('购物车功能', () => {
// 每个测试前都清空购物车,避免相互影响
beforeEach(() => {
cart.items = [];
});
it('添加一个商品后,总数应该是1', () => {
cart.addItem('苹果');
expect(cart.getTotal()).toBe(1);
});
it('添加两个商品后,总数应该是2', () => {
cart.addItem('香蕉');
cart.addItem('橘子');
expect(cart.getTotal()).toBe(2);
});
});
总结一下
Jasmine 核心就是:用 describe
分组,it
写测试点,expect
做判断。
本质上,写测试就像给代码 "写说明书":不仅能保证功能正确,以后改代码时,跑一遍测试就知道有没有弄坏原来的功能 ------ 这就是为什么大型项目(比如 Vue)都离不开测试啦~