Jasmine单元测试

Jasmine 是流行的 JavaScript 单元测试框架之一,能够测试同步和异步 JavaScript 代码。
它用于 BDD(行为驱动开发)编程,它更关注业务价值而不是技术细节。

Jasmine匹配器

在第一个例子中,我们看到了 toEqualtoThrow函数的用法。
它们是匹配器,用于比较任何 jasmine 测试的实际和预期输出。
如果它可以帮助你,你就像java断言一样。

让我们列出所有此类 Jasmine 匹配器,它们可以实现更强大和更有意义的测试规范。

Matcher目的
toBe()如果实际值与预期值的类型和值相同,则通过。它与 === 运算符比较
toEqual()适用于简单的文字和变量;
也适用于对象
toMatch()检查值是否与字符串或者正则表达式匹配
toBeDefined()确保定义了属性或者值
toBeUndefined()确保属性或者值未定义
toBeNull()确保属性或者值为空。
toBeTruthy()确保属性或者值是“true”
ToBeFalsy()确保属性或者值是“false”
toContain()检查字符串或者数组是否包含子字符串或者项目。
toBeLessThan()对于小于的数学比较
toBeGreaterThan()对于大于的数学比较
toBeCloseTo()用于精确的数学比较
toThrow()用于测试函数是否抛出异常
toThrowError()用于测试特定抛出的异常

Jasmine not关键字可以与每个匹配器的条件一起使用,以反转结果。
例如

expect(actual).not.toBe(expected);
expect(actual).not.toBeDefined(expected);

设置和拆卸

为了设置和拆除,Jasmine 在套件级别提供了两个全局函数,例如:beforeEach()afterEach()

beforeEach()

beforeEach函数在调用它的 describe()中的每个规范之前被调用一次。

afterEach()

afterEach函数在每个规范之后被调用一次。

在实践中,规范变量(是任何)在顶级范围定义 - describe块 - 并且初始化代码被移动到 beforeEach函数中。
afterEach函数在继续之前重置变量。
这有助于开发人员不要为每个规范重复设置和完成代码。

Jasmine 设置配置

首先下载 jasmine 框架并将其解压缩到项目文件夹中。

我建议在/js或者/javascript文件夹下创建一个单独的文件夹/jasmine,该文件夹可能已经存在于应用程序中。

我们将在分发包中获得以下四个文件夹/文件:

  • /src: 包含要测试的 JavaScript 源文件
  • /lib: 包含框架文件
  • /spec: 包含 JavaScript 测试文件
  • SpecRunner.html: 是测试用例运行器 HTML 文件

你可以删除/src文件夹;并从“SpecRunner.html”文件中的当前位置引用源文件。
默认文件如下所示,我们需要更改包含在 /src/spec文件夹中的文件。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Jasmine Spec Runner v2.4.1</title>

	<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.4.1/jasmine_favicon.png">
	<link rel="stylesheet" href="lib/jasmine-2.4.1/jasmine.css">

	<script src="lib/jasmine-2.4.1/jasmine.js"></script>
	<script src="lib/jasmine-2.4.1/jasmine-html.js"></script>
	<script src="lib/jasmine-2.4.1/boot.js"></script>

	<!-- include source files here... -->
	<script src="src/Player.js"></script>
	<script src="src/Song.js"></script>

	<!-- include spec files here... -->
	<script src="spec/SpecHelper.js"></script>
	<script src="spec/PlayerSpec.js"></script>
</head>
<body></body>
</html>

为了专注于 Jasmine 的能力,我们创建一个简单的 JS 文件“MathUtils.js”,其中包含一些基本操作,我们将对这些功能进行单元测试。

MathUtils = function() {};
MathUtils.prototype.sum = function(number1, number2) {
		return number1 + number2;
}
MathUtils.prototype.substract = function(number1, number2) {
	return number1 - number2;
}
MathUtils.prototype.multiply = function(number1, number2) {
	return number1 * number2;
}
MathUtils.prototype.divide = function(number1, number2) {
	return number1 / number2;
}
MathUtils.prototype.average = function(number1, number2) {
	return (number1 + number2) / 2;
}
MathUtils.prototype.factorial = function(number) {
	if (number < 0) {
		throw new Error("There is no factorial for negative numbers");
	} else if (number == 1 || number == 0) {
		return 1;
	} else {
		return number * this.factorial(number - 1);
	}
}

SpecRunner.html中添加文件引用后,文件内容将是:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Jasmine Spec Runner v2.4.1</title>

	<link rel="shortcut icon" type="image/png"
		href="lib/jasmine-2.4.1/jasmine_favicon.png">
	<link rel="stylesheet" href="lib/jasmine-2.4.1/jasmine.css">

	<script src="lib/jasmine-2.4.1/jasmine.js"></script>
	<script src="lib/jasmine-2.4.1/jasmine-html.js"></script>
	<script src="lib/jasmine-2.4.1/boot.js"></script>

	<!-- include source files here... -->
	<script src="../MathUtils.js"></script>

	<!-- include spec files here... -->
	<script src="spec/MathUtils.js"></script>
</head>
<body></body>
</html>
欢迎来到之路教程(on itroad-com)

Jasmine描述块

在 Jasmine 中,describe函数用于对相关规范进行分组。
字符串参数用于命名规范的集合,并将与规范连接以形成规范的全名。
这有助于在大型套件中查找规格。

好消息是,我们也可以嵌套 describe块。
在嵌套 describe的情况下,在执行规范之前,Jasmine 按顺序向下执行每个 beforeEach函数,然后执行规范,最后向上执行每个 afterEach函数。

替换MathUtilSpecs.js中代码:

describe("Nested Describe Demo", function() {
	beforeEach(function() {
		console.log("beforeEach level 1");
	});
	describe("MyTest level2", function() {
		beforeEach(function() {
			console.log("beforeEach level 2");
		});
		describe("MyTest level3", function() {
			beforeEach(function() {
				console.log("beforeEach level 3");
			});
			it("is a simple spec in level3", function() {
				console.log("A simple spec in level 3");
				expect(true).toBe(true);
			});
			afterEach(function() {
				console.log("afterEach level 3");
			});
		});
		afterEach(function() {
			console.log("afterEach level 2");
		});
	});
	afterEach(function() {
		console.log("afterEach level 1");
	});
});

现在通过在浏览器中打开“SpecRunner.html”来执行这个文件。
观察控制台输出,它写成:

beforeEach level 1 
beforeEach level 2 
beforeEach level 3 
A simple spec in level 3 
afterEach level 3 
afterEach level 2 
afterEach level 1

Jasmine suite 和 spec

在 Jasmine 中,有两个重要的术语 suite 和 spec 。

suite

Jasmine 套件是一组测试用例,可用于测试 JavaScript 代码(JavaScript 对象或者函数)的特定行为。
这从调用 Jasmine 全局函数 describe开始,其中有两个参数,第一个参数表示测试套件的标题,第二个参数表示实现测试套件的函数。

//This is test suite
describe("Test Suite", function() {
  	//.....
});

Spec

Jasmine 规范(Spec)代表测试套件中的一个测试用例。
这从调用 Jasmine 全局函数 it开始,它有两个参数,第一个参数表示规范的标题,第二个参数表示实现测试用例的函数。

实际上,规范包含一个或者多个期望。
每个期望代表一个断言,可以是 true或者 false
为了通过规范,规范中的所有期望都必须为“true”。
如果规范中的一个或者多个期望为“false”,则规范失败。

//This is test suite
describe("Test Suite", function() {
  	it("test spec", function() {
   		expect( expression ).toEqual(true);
  	});	
});

让我们开始为MathUtils.js编写单元测试以更好地理解套件和规范。
我们将在 spec/MathUtils.js中编写这些规范。

describe("MathUtils", function() {
	var calc;
	//This will be called before running each spec
	beforeEach(function() {
		calc = new MathUtils();
	});
	describe("when calc is used to peform basic math operations", function(){

		//Spec for sum operation
		it("should be able to calculate sum of 3 and 5", function() {
			expect(calc.sum(3,5)).toEqual(8);
		});
		//Spec for multiply operation
		it("should be able to multiply 10 and 40", function() {
			expect(calc.multiply(10, 40)).toEqual(400);
		});
		//Spec for factorial operation for positive number
		it("should be able to calculate factorial of 9", function() {
			expect(calc.factorial(9)).toEqual(362880);
		});

		//Spec for factorial operation for negative number
		it("should be able to throw error in factorial operation when the number is negative", function() {
			expect(function() { 
				calc.factorial(-7)
	        }).toThrowError(Error);
		});

	});
});

在浏览器中打开 SpecRunner.html文件时,运行规范并在浏览器中呈现结果。

禁用Suite 和Spec

很多时候,出于各种原因,我们可能希望禁用Suite一段时间。
在这种情况下,我们不需要删除代码,而只需在 describe的开头添加字符 x即可生成 if xdescribe

这些套件和其中的任何规格在运行时都会被跳过,因此它们的结果不会出现在结果中。

xdescribe("MathUtils", function() {
	//code
});

如果我们不想禁用整个套件,而只想禁用某个规范测试,则将 x放在该规范本身之前,这次只会跳过该规范。

describe("MathUtils", function() {
	//Spec for sum operation
	xit("should be able to calculate the sum of two numbers", function() {
		expect(10).toBeSumOf(7, 3);
	});
});
日期:2020-09-17 00:10:38 来源:oir作者:oir