本文略译自《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[注]的Suite名,一个称为 Specs 实现方法,一个套装由多个规格测试组成。
注:BDD扩展于TDD,使用不同方式编写测试用例,这些测试用任何人(不一定是程序员)都可以阅读和理解的自然语言来测试软件行为(需求)。单元测试的名称通常以单词“should”开头,并且按照业务价值的顺序编写。
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.
toBeLessThan/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。
Be First to Comment