测试驱动开发 (TDD) 是一种用于编写干净、无错误代码的强大方法。在本文中,我们将探索如何使用 Bun 的内置测试运行器 Bun Test 来实现 TDD,该运行器以其速度和简单性而闻名。
测试驱动开发(TDD)是一种在代码之前编写测试的软件开发实践。 TDD 实践指导实现并通过迭代编写、测试和重构周期确保功能。
TDD 是一个遵循以下步骤的开发过程:
这个迭代过程旨在生成健壮且经过良好测试的代码。
如果您尚未安装 Bun,请按照 Bun JavaScript 文档中的说明进行安装。
然后,初始化一个新项目:
bun init
➜ example bun init bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit package name (example): entry point (index.ts): Done! A package.json file was saved in the current directory.
在tests目录中创建一个测试文件(例如tests/example.test.js)。 Bun会自动检测以.test.ts或.test.js结尾的文件进行测试。
mkdir tests touch tests/example.test.js
让我们从一个简单的例子开始。
我们将创建一个计算器文件来实现一些数学函数。
我们首先关注一个简单的函数,比如 sum(),尽管 JavaScript 已经有一个原生的加法运算符。这使我们能够专注于构建测试而不是逻辑的复杂性。
计划如下:
在tests/calculator.test.js 文件中,您可以实现您的测试:
import { describe, expect, it } from "bun:test"; import { sum } from "../calculator"; describe("sum function", () => { it("should return the sum of two numbers (both are positive)", () => { expect(sum(2, 3)).toBe(5); }); it("should return the sum of two numbers (one is negative)", () => { expect(sum(-1, 2)).toBe(1); }); });
这些测试验证计算器模块中定义的 sum() 函数的行为。这些测试是使用 Bun 的测试库编写的,并组织在名为“sum function”的描述块中。 describe() 块有助于对“相似”测试进行分组。每个 it() 块指定要测试的特定场景。以下是每个测试的作用:
这些测试确保 sum 函数的行为符合基本加法场景的预期,涵盖正数和混合(正和负)输入。
现在,您可以创建导出 sum() 函数的计算器模块。
在calculator.ts文件中:
bun init
该函数的第一个版本返回一个硬编码值,因此我预计测试会失败。
运行测试:
➜ example bun init bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit package name (example): entry point (index.ts): Done! A package.json file was saved in the current directory.
现在我们可以调整计算器中sum()函数的逻辑了。调整sum()函数的逻辑:
mkdir tests touch tests/example.test.js
现在,如果您运行测试,您将获得“绿色”✅ 状态。
如果你想在不同的场景(输入值)下运行相同的测试,可以使用each()方法。
import { describe, expect, it } from "bun:test"; import { sum } from "../calculator"; describe("sum function", () => { it("should return the sum of two numbers (both are positive)", () => { expect(sum(2, 3)).toBe(5); }); it("should return the sum of two numbers (one is negative)", () => { expect(sum(-1, 2)).toBe(1); }); });
使用数据集驱动的方法,此代码测试计算器模块中的 sum 函数。 it.each() 方法用于通过迭代输入和预期输出的数据集来简化重复的测试用例。以下是其工作原理的详细说明:
首先,您可以定义一个数据集
export function sum(a: number, b: number) { // Function yet to be implemented return 0; }
数据集是一个数组的数组。每个内部数组代表一个测试用例,其中元素对应于:
describe 函数将与 sum 函数相关的所有测试分组到一个块下,以便更好地组织。
在describe()块中,it.each(dataset)迭代数据集数组中的每一行。
“%d 和 %d 的和应该是 %d”是测试的描述模板,其中 %d 在每次迭代期间被替换为数据集中的实际数字。
例如,第一次迭代生成描述:“2 和 3 的总和应为 5”。
在回调函数(a,b,expected)中,数据集中每一行的元素被解构为变量:a,b,expected。然后,在测试中,使用 a 和 b 调用 sum 函数,并使用 Expect() 检查结果以确保其与预期相符。
为了展示 TDD 的另一个示例,让我们在计算器模块中实现一个平均值函数,用于计算数字数组的平均值。遵循 TDD 方法,我们将从编写测试开始。
在已经存在的calculator.test.js中添加这些特定于mean()函数的测试:
bun init
现在在calculator.ts文件中,添加mean()函数:
➜ example bun init bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit package name (example): entry point (index.ts): Done! A package.json file was saved in the current directory.
现在您可以再次执行测试
mkdir tests touch tests/example.test.js
所有测试都应该通过。
在这种情况下,实现已经经过测试,因此不需要进一步重构。但是,请务必花时间检查您的代码以进行改进。
测试覆盖率是衡量自动化测试期间执行的代码库百分比的指标。它提供了有关测试验证代码的效果的见解。
Bun 测试覆盖率有助于识别“线路覆盖率”。
行覆盖率检查测试套件期间是否执行了每行代码。
运行测试覆盖率:
import { describe, expect, it } from "bun:test"; import { sum } from "../calculator"; describe("sum function", () => { it("should return the sum of two numbers (both are positive)", () => { expect(sum(2, 3)).toBe(5); }); it("should return the sum of two numbers (one is negative)", () => { expect(sum(-1, 2)).toBe(1); }); });
虽然高测试覆盖率很重要,但这并不是衡量代码质量的唯一标准。旨在进行有意义的测试,重点关注应用程序的功能、边缘情况和关键部分。实现 100% 的覆盖率是理想的,但不要以编写不必要或琐碎的测试为代价。
使用 Bun Test 的测试驱动开发 (TDD) 使开发人员能够通过首先关注需求并通过迭代测试确保功能来编写干净、可维护且健壮的代码。通过利用 Bun 快速高效的测试工具,您可以简化开发流程并自信地处理边缘情况。采用 TDD 不仅可以提高代码质量,还可以培养从一开始就编写可测试的模块化代码的心态。从小事做起,经常迭代,让您的测试指导您的实施。
以上是带有 Bun Test 的测试驱动开发 (TDD)的详细内容。更多信息请关注PHP中文网其他相关文章!