Javascript单元测试框架Jasmine
一、简介
Jasmine是一个用于测试JavaScript代码的行为驱动开发框架,它不依赖于任何其他JavaScript框架,也不需要DOM,它的语法简单明了,可以轻松地上手编写测试。
二、安装
- 安装
执行 npm install jasmine --save-dev
- 配置
在项目的package.json
中设置test script:
"script": { "test": "jasmine" }
或者在npm init
时直接设置test script:
{
"name": "study-jasmine",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "jasmine"
},
"author": "albert",
"license": "ISC",
"devDependencies": {
"jasmine": "^2.8.0"
}
}
三、初始化项目并生成样例
通过创建一个spec
目录和jasmine的配置文件jasmine.json
初始化jasmine项目。
- 初始化
jasmine init
此命令执行完之后会生成 spec\support\jasmine.json
文件:
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": false
}
说明:
`spec_dir`: 测试用例(spec)目录,自定义的目录必须相对于此路径
`spec_files`: 测试用例(spec)文件,路径相对于spec_dir配置的目录路径
`helpers`: 测试用例执行前文件,路径相对于spec_dir配置的目录路径
`stopSpecOnExpectationFailure`: it函数中的第一个期望失败后停止执行
`random`: 使用半随机(semi-random)顺序运行测试用例
备注:执行此命令需要确定已全局安装jasmine(npm install jasmine -g)
- 生成样例文件
jasmine examples
四、运行测试
使用 jasmine
或 npm test
运行测试,或者指定运行单个spec文件:jasmine spec/jasmine_examples/PlayerSpec.js
五、样例分析
jasmine examples
命令执行后生成了以下目录/文件:
lib\jasmine_examples:Player.js 、 Song.js
spec\helpers\jasmine_examples: SpecHelper.js
spec\jasmine_examples\PlayerSpec.js
1、Song.js
一个简单的歌曲类,只有一个“标记为喜欢歌曲”的方法。
function Song() {
}
Song.prototype.persistFavoriteStatus = function(value) {
// something complicated
throw new Error("not yet implemented");
};
module.exports = Song;
2、Player.js
播放器类,共有四个方法:播放、暂停、继续、标记为喜欢。
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
module.exports = Player;
3、SpecHelper.js
此js中调用了beforeEach方法,beforeEach方法在describe(见PlayerSpec.js)中的每个测试用例(Spec)执行前执行,与之相对的是afterEach方法是在每个测试用例执行后执行。
此js在beforeEach的回调中使用addMatchers方法添加了自定义匹配器(matcher),定义toBePlaying的判断规则,此方法需要返回一个compare函数,compare函数将在检查期望值时被调用,compare函数接收的第一个参数是expect()函数的参数(actual),第二个参数(可选)是toBePlaying函数被调用时传的参数。compare函数必须返回一个包含pass属性(boolean类型)的对象,此属性值表明匹配的结果;还可以在返回对象中增加message属性自定义匹配结果信息。
beforeEach(function () {
jasmine.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
}
}
};
}
});
});
4、PlayerSpec.js
此文件是Player.js的测试用例文件,共有五个测试用例。
describe("Player", function() {
var Player = require('../../lib/jasmine_examples/Player');
var Song = require('../../lib/jasmine_examples/Song');
var player;
var song;
beforeEach(function() {
player = new Player();
song = new Song();
});
it("should be able to play a Song", function() {
player.play(song);
expect(player.currentlyPlayingSong).toEqual(song);
//demonstrates use of custom matcher
expect(player).toBePlaying(song);
});
describe("when song has been paused", function() {
beforeEach(function() {
player.play(song);
player.pause();
});
it("should indicate that the song is currently paused", function() {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", function() {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", function() {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", function() {
it("should throw an exception if song is already playing", function() {
player.play(song);
expect(function() {
player.resume();
}).toThrowError("song is already playing");
});
});
});
-
说明:
-
describe(description, specDefinitions)
:定义一组测试用例(测试集suite),第一个参数是suite的描述,第二个参数是执行内部定义的测试集(suites)和测试用例(specs)的函数。
-
it(description, testFunctionopt, timeoutopt)
定义单个的测试用例(spec),一个测试用例包含一个或多个期望来测试代码的正确性。第一个参数是测试用例的描述,第二个参数是对代码测试的函数,第三个参数是对异步测试用例的超时时间。
-
expect(actual)
为测试用例创建一个期望。
-
附:
- Jasmine官网:https://jasmine.github.io/
- Jasmine API:https://jasmine.github.io/api/edge/