|
自动化测试将被用于进一步的任务中,并且还将被广泛应用在实际项目中。
我们为什么需要测试?
当我们在写一个函数时,我们通常可以想象出它应该做什么:哪些参数会给出哪些结果。
在开发期间,我们可以通过运行程序来检查它并将结果与预期进行比较。例如,我们可以在控制台中这么做。
如果出了问题 —— 那么我们会修复代码,然后再一次运行并检查结果 —— 直到它工作为止。
但这样的手动“重新运行”是不完美的。
当通过手动重新运行来测试代码时,很容易漏掉一些东西。
例如,我们要创建一个函数 f。写一些代码,然后测试:f(1) 可以执行,但是 f(2) 不执行。我们修复了一下代码,现在 f(2) 可以执行了。看起来已经搞定了?但是我们忘了重新测试 f(1)。这样有可能会导致出现错误。
这是非常典型的。当我们在开发一些东西时,我们会保留很多可能需要的用例。但是不要想着程序员在每一次代码修改后都去检查所有的案例。所以这就很容易造成修复了一个问题却造成另一个问题的情况。
自动化测试意味着测试是独立于代码的。它们以各种方式运行我们的函数,并将结果与预期结果进行比较。
行为驱动开发(BDD)
我们来使用一种名为 行为驱动开发 或简言为 BDD 的技术。
BDD 包含了三部分内容:测试、文档和示例。
为了理解 BDD,我们将研究一个实际的开发案例。
开发 “pow”:规范
我们想要创建一个函数 pow(x, n) 来计算 x 的 n 次幂(n 为整数)。我们假设 n≥0。
这个任务只是一个例子:JavaScript 中有一个 ** 运算符可以用于幂运算。但是在这里我们专注于可以应用于更复杂任务的开发流程上。
在创建函数 pow 的代码之前,我们可以想象函数应该做什么并且描述出来。
这样的描述被称作 规范(specification, spec),包含用例的描述以及针对它们的测试,如下所示:
describe("pow", function() {
it("raises to n-th power", function() {
assert.equal(pow(2, 3), 8);
});
});
正如你所看到的,一个规范包含三个主要的模块:
describe("title", function() { ... })
表示我们正在描述的功能是什么。在我们的例子中我们正在描述函数 pow。用于组织“工人(workers)” —— it 代码块。
it("use case description", function() { ... })
it 里面的描述部分,我们以一种 易于理解 的方式描述特定的用例,第二个参数是用于对其进行测试的函数。
assert.equal(value1, value2)
it 块中的代码,如果实现是正确的,它应该在执行的时候不产生任何错误。
assert.* 函数用于检查 pow 函数是否按照预期工作。在这里我们使用了其中之一 —— assert.equal,它会对参数进行比较,如果它们不相等则会抛出一个错误。这里它检查了 pow(2, 3) 的值是否等于 8。还有其他类型的比较和检查,我们将在后面介绍到。
规范可以被执行,它将运行在 it 块中指定的测试。我们稍后会看到。
|
|