使用Jasmine测试JavaScript(一)——基本概念
2023 review: 本文只是介绍了工具,并没有触及理论,有模块测试的理论——模块的设计,开发,测试和文档。
本文略译自《Testing JavaScript Using the Jasmine Framework》
在过去,JavaScript代码是出了名很难测试的;幸好,得益于互联网和移动互联网的发展,JS测试工具 伴随JS开发生态圈的发展,被陆续开发出来。当前流行的JS测试工具/框架,包括 Jasmine,qUnit,YUI Test等。
其实大多数JS应用框架都配备了自己的测试工具/框架。框架相关的测试工具,和通用的测试工具(例如 Jasmine )都有自己的特点和适用性。另一个 选择测试框架的指标,就是测试工具是否依赖浏览器,如果不依赖浏览器,那么测试工具易用性会更高。
Jasmine三个基本概念
不管你过去是否有使用测试工具的经验,上手Jasmine使用不需要太多时间,了解几基本概念就可以了。
Jasmine 第一个重要概念是Suite
Suite——【测试套装】表征一组相关的【测验】(test case);
套装(Suite)由一集(一个以上)具体【测验】组成——将测验的结果(叫actual)与预期的值(expected value)进行比对。测验任务在jasmine称为 Expectations。
在技术上,套装(Suite)由全局API describe()
定义:两个参数,一个BDD注1的Suite名,一个称为 Specs 实现方法,一个套装由多个规格测试组成。
Jasmine 第二个重要概念是Specs
在【套装】和【测验】之间还有一层组织,它就是软件规格(Specs)。软件规格就像套装概念一样,是逻辑的;
在技术上,规格(Specs)由全局API it()
定义:两个参数,一个BDD的 Specs 名,一个 expectation 的实现方法。
it()
function内可按需要使用变量(为什么要变量,这根据测验任务需要),并且有一个以上具体测验语句(Expectations)。
Jasmine 第三个重要概念是 Expectations
【完整的测验语句】由测验目标( expect()
method)和断言组成,断言Jasmine称为匹配函数(Matcher),有断言才能产生一个真值,表明测验是否通过。以下是一个简单的例子:
describe("Stock Portfolio App Tests", function() {
it("calcSideFundInterest() should return a value that is greater than the supplied fund value.", function() {
var calcSideFundInterest = function(fundValue, dailyInt, period) {
return fundValue * (dailyInt * period);
};
var fundValue = 1000,
dailyInt = 0.00356,
period = 7;
var result = calcSideFundInterest(fundValue, dailyInt, period);
expect(result).toBeGreaterThan(fundValue);
});
});
综上所述, 逻辑上,每个Suite(describe)有一个以上的Spec(it),而一个Spec又有一个以上的test case(expect.matcher)
预定义 Matchers
在上面的例子里,toBeGreaterThan()就是匹配函数,或者 断言操作。Jasmine预定义了很多断言操作给我们使用,包括以下:
- toBe: represents the exact equality (===) operator.
- toEqual: represents the regular equality (==) operator.
- toMatch: calls the RegExp match() method behind the scenes to compare string data.
- toBeDefined: opposite of the JS "undefined" constant.
- toBeUndefined: tests the actual against "undefined".
- toBeNull: tests the actual against a null value - useful for certain functions that may return null, like those of regular expressions (same as toBe(null))
- toBeTruthy: simulates JavaScript boolean casting.
- toBeFalsy: like toBeTruthy, but tests against anything that evaluates to false, such as empty strings, zero, undefined, etc…
- toContain: performs a search on an array for the actual value.
- oBeLessThan/toBeGreaterThan: for numerical comparisons.
- toBeCloseTo: for floating point comparisons.
- toThrow: for catching expected exceptions.
此外,还有一个取反的断言操作not,例如 expect(false).not.toBe(true)。
Jasmine 支持自定义断言操作,本文不介绍自定义方法,只是提示。
规格测试对象实例的事件勾子
Jasmine为【规格测验】设计了生命勾子,每一次的规格测验的【前置条件】和【事后清理】分别在beforeEach()
和 afterEach()
里处理。可见规格测验才是测验对象实例。
describe("Stock Portfolio App Tests", function() {
var presentValue,
previousValue,
aPercentChanges;
beforeEach(function() {
presentValue = 110;
previousValue = 100;
aPercentChanges = [];
});
afterEach(function() {
presentValue = 0;
previousValue = 0;
aPercentChanges = [];
});
it("calcWeeklyPercentChange() should return the change between two numbers as a percentage.", function() {
var calcWeeklyPercentChange = function(presentValue, previousValue, aPercentChanges) {
var percentChange = presentValue / previousValue - 1;
aPercentChanges.push(percentChange);
return percentChange;
};
//actually returns 0.10000000000000009!
var result = calcWeeklyPercentChange(presentValue, previousValue, aPercentChanges);
expect(result).toBeCloseTo(0.1);
expect(aPercentChanges.length).toEqual(1);
});
it("The aPercentChanges array should now be empty.", function() {
expect(aPercentChanges.length).toEqual(0);
});
});
小结
到此,你学会了使用Jasmine的基本功能了。下一次,我们将讲如何在浏览器上进行测试,并且如何使用spy。
参考
https://jasmine.github.io/api/edge/matchers.html
- BDD扩展于TDD,使用不同方式编写测试用例,这些测试用任何人(不一定是程序员)都可以阅读和理解的自然语言来测试软件行为(需求)。单元测试的名称通常以单词“should”开头,并且按照业务价值的顺序编写。↩