首页 > web前端 > js教程 > 带有 Bun Test 的测试驱动开发 (TDD)

带有 Bun Test 的测试驱动开发 (TDD)

Patricia Arquette
发布: 2024-12-29 17:15:15
原创
951 人浏览过

测试驱动开发 (TDD) 是一种用于编写干净、无错误代码的强大方法。在本文中,我们将探索如何使用 Bun 的内置测试运行器 Bun Test 来实现 TDD,该运行器以其速度和简单性而闻名。

什么是TDD?

测试驱动开发(TDD)是一种在代码之前编写测试的软件开发实践。 TDD 实践指导实现并通过迭代编写、测试和重构周期确保功能。

TDD 是一个遵循以下步骤的开发过程:

  • 为所需的功能编写测试。
  • 定义您想要涵盖的所有测试场景。
  • 运行测试并验证它是否失败(因为功能可能不完整或尚未涵盖所有场景)。
  • 更新并重构代码,使测试通过,同时确保所有测试成功。

这个迭代过程旨在生成健壮且经过良好测试的代码。

使用 Bun 设置您的 JavaScript 项目

如果您尚未安装 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 已经有一个原生的加法运算符。这使我们能够专注于构建测试而不是逻辑的复杂性。
计划如下:

  • 创建一个calculator.ts 文件,我们将在其中定义一个最初返回 0 的 sum() 函数。
  • 为 sum() 函数编写测试,涵盖多个测试用例。
  • 运行测试并确认它们失败。
  • 更新 sum() 函数的逻辑以使测试通过。
  • 重新运行测试以确保我们的实施正确。

创建计算器.test.js 文件

在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() 块指定要测试的特定场景。以下是每个测试的作用:

  1. 测试:两个正数相加
    • 描述:“应返回两个数字之和(均为正数)”
    • 此测试检查 sum 函数是否正确计算两个正整数的和。
    • 示例:sum(2, 3) 预期返回 5。
  2. 测试:将负数和正数相加
    • 描述:“应返回两个数字之和(其中一个为负数)”
    • 此测试验证 sum 函数是否可以正确处理一个数字为负数的情况。
    • 示例:sum(-1, 2) 预期返回 1。

这些测试确保 sum 函数的行为符合基本加法场景的预期,涵盖正数和混合(正和负)输入。

创建计算器.ts 文件

现在,您可以创建导出 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.
登录后复制
登录后复制
登录后复制

Test-Driven Development (TDD) with Bun Test

现在我们可以调整计算器中sum()函数的逻辑了。调整sum()函数的逻辑:

mkdir tests
touch tests/example.test.js
登录后复制
登录后复制
登录后复制

现在,如果您运行测试,您将获得“绿色”✅ 状态。

Test-Driven Development (TDD) with Bun Test

使用数据集重构测试

如果你想在不同的场景(输入值)下运行相同的测试,可以使用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;
}
登录后复制

数据集是一个数组的数组。每个内部数组代表一个测试用例,其中元素对应于:

  • a(要添加的第一个数字),
  • b(要添加的第二个数字),
  • 预期(sum(a, b) 的预期结果)。

describe 函数将与 sum 函数相关的所有测试分组到一个块下,以便更好地组织。

在describe()块中,it.each(dataset)迭代数据集数组中的每一行。
“%d 和 %d 的和应该是 %d”是测试的描述模板,其中 %d 在每次迭代期间被替换为数据集中的实际数字。
例如,第一次迭代生成描述:“2 和 3 的总和应为 5”。

在回调函数(a,b,expected)中,数据集中每一行的元素被解构为变量:a,b,expected。然后,在测试中,使用 a 和 b 调用 sum 函数,并使用 Expect() 检查结果以确保其与预期相符。

为什么使用 it.each() (或 test.each())?

  • 效率:您可以在单个数据集中定义所有测试用例并循环遍历它们,而不是为每个案例编写单独的 it() 或 test() 块。
  • 可读性:测试逻辑简洁,数据集使得添加或修改测试用例变得容易,无需重复代码。
  • 可扩展性:在处理多个测试用例时非常有用,特别是当被测试的逻辑在不同用例之间相似时。

另一个实际例子:计算平均值

为了展示 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
登录后复制
登录后复制
登录后复制

Test-Driven Development (TDD) with Bun Test

所有测试都应该通过。
在这种情况下,实现已经经过测试,因此不需要进一步重构。但是,请务必花时间检查您的代码以进行改进。

测试覆盖率

测试覆盖率是衡量自动化测试期间执行的代码库百分比的指标。它提供了有关测试验证代码的效果的见解。
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);
  });
});
登录后复制
登录后复制
登录后复制

Test-Driven Development (TDD) with Bun Test

为什么覆盖范围很重要?

  • 识别测试中的差距:覆盖率报告突出显示代码的哪些部分未经过测试。这可以帮助您确保关键逻辑不被忽视。
  • 提高代码质量:高覆盖率确保边缘情况、错误处理和业务逻辑得到彻底测试,减少出现错误的可能性。
  • 对重构充满信心:如果您有经过良好测试的代码库,您就可以充满信心地进行重构,因为您知道您的测试会捕获回归。
  • 更好的维护:具有高测试覆盖率的代码库更容易维护,因为您可以在更新期间检测到意外的更改或副作用。
  • 支持 TDD:对于实践测试驱动开发的开发人员来说,监控覆盖范围可确保测试与实现保持一致。

平衡覆盖目标

虽然高测试覆盖率很重要,但这并不是衡量代码质量的唯一标准。旨在进行有意义的测试,重点关注应用程序的功能、边缘情况和关键部分。实现 100% 的覆盖率是理想的,但不要以编写不必要或琐碎的测试为代价。

结论

使用 Bun Test 的测试驱动开发 (TDD) 使开发人员能够通过首先关注需求并通过迭代测试确保功能来编写干净、可维护且健壮的代码。通过利用 Bun 快速高效的测试工具,您可以简化开发流程并自信地处理边缘情况。采用 TDD 不仅可以提高代码质量,还可以培养从一开始就编写可测试的模块化代码的心态。从小事做起,经常迭代,让您的测试指导您的实施。

以上是带有 Bun Test 的测试驱动开发 (TDD)的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板