paint-brush
Jasmine:关于纯函数和基本测试的初学者友好指南经过@marcinwosinek
181 讀數

Jasmine:关于纯函数和基本测试的初学者友好指南

经过 Marcin Wosinek6m2024/02/11
Read on Terminal Reader

太長; 讀書

纯函数是单元测试的完美案例。对于给定的输入,我们总是期望相同的输出——不涉及内部状态。让我们看一些示例和一些简单的测试,以检查这些方法是否按预期工作。
featured image - Jasmine:关于纯函数和基本测试的初学者友好指南
Marcin Wosinek HackerNoon profile picture

纯函数是单元测试的完美案例。对于给定的输入,我们总是期望相同的输出——不涉及内部状态。让我们看一些示例和一些简单的测试,以检查这些方法是否按预期工作。

茉莉花

Jasmine 是 JavaScript 的单元测试框架。它可以在 Node.js 或浏览器上运行测试。它用在 Angular 框架中,在基于 Angular 的项目中尤其流行。对于 Vanilla JS 项目或基于其他框架的项目来说,它是一个不错的选择。

快乐路径测试

快乐的路径测试是当我们使用预期正常工作的输入来测试方法时。这些论据是有效的,并且在合理范围内。这些测试检查方法是否正确完成其工作 - 测试用例应该是如何在其文档中解释该方法的简单示例。


伪代码示例:

  • expect(add(2, 2)).toBe(4) ,


  • expect(concatenate(“Lorem”, “Ipsum”)).toBe(“LoremIpsum”)


这些测试旨在在方法关键行为被破坏时自动捕获它。

方法

让我们看一些简单的方法:在一些实际应用程序中我们可能需要的简单操作。


所有的实现都大大简化了——如果我们为它们提供与预期略有不同的参数,所有方法都会以一种丑陋的方式被破坏。该代码远非健壮。

迎接

用名字和姓氏向用户打招呼的方法:

 export function greet(name, surname) { return `Hello ${name} ${surname}!`; }

短日期

shortDate是一种格式化方法,它接受日期对象并将其格式化为短字符串。代码:

 export function shortDate(date) { return date.toISOString().substring(0, 10); }

省略

ellipsis接受一个长文本字符串和一个可选的长度参数,然后修剪该字符串以适合限制:

 export function ellipsis(text, length = 50) { if (text.length > length) { return text.substring(0, length) + "…"; } return text; }

翻译

一种为keylang对提供翻译后的字符串值的方法。它是可以用更高级的翻译库替换的简化实现。

 export function translate(key, lang = "en") { switch (lang) { case "en": switch (key) { case "hello": return "Hello!"; } case "pl": switch (key) { case "hello": return "Cześć!"; } } }

申请折扣

对价格应用百分比折扣的方法。这种幼稚的实现可能让人感觉有点矫枉过正,但后来,当我们开始调查边缘情况时,它会变得更加有趣。

 export function applyDiscount(price, discountPercentage) { return price - (price * discountPercentage) / 100; }

计算价格

该函数计算以给定价格购买多个单位时的总价。添加有趣的边缘情况后,它也会变得更加复杂。

 export function calculatePrice(unitPrice, quantity) { return unitPrice * quantity; }

完整的JS代码

完整的JS代码, src/main.js

 export function greet(name, surname) { return `Hello ${name} ${surname}!`; } export function shortDate(date) { return date.toISOString().substring(0, 10); } export function ellipsis(text, length = 50) { if (text.length > length) { return text.substring(0, length) + "…"; } return text; } export function translate(key, lang = "en") { switch (lang) { case "en": switch (key) { case "hello": return "Hello!"; } case "pl": switch (key) { case "hello": return "Cześć!"; } } } export function applyDiscount(price, discountPercentage) { return price - (price * discountPercentage) / 100; } export function calculatePrice(unitPrice, quantity) { return unitPrice * quantity; }

添加 Jasmine 测试

要添加 Jasmine,我们首先将文件夹转换为 npm 包:

 $ npm init -y Wrote to …/package.json: …


然后我们就可以安装 Jasmine 包了:

 $ npm install --save-dev jasmine added 42 packages, and audited 43 packages in 2s 13 packages are looking for funding run `npm fund` for details found 0 vulnerabilities


然后我们就可以生成Jasmine使用的文件夹和文件了:

 $ npx jasmine init (no output)


该命令生成以下内容:

  • spec/ — 一个文件夹,我们可以在其中放置*.spec.js文件和测试,并且


  • spec/support/jasmine.json — 包含 Jasmine 配置的文件。

单元测试

对于以下单元测试,我仅关注快乐路径 - 我检查结果是否符合合理输入的预期。该测试应该是不言自明的,所以让我们看一下它们:

 import { greet, shortDate, ellipsis, translate, applyDiscount, calculatePrice, } from "../src/main.js"; describe("main", () => { describe("greet", () => { it("should greet by name and surname", () => { expect(greet("Lorem", "Ipsum")).toEqual("Hello Lorem Ipsum!"); }); }); describe("shortDate", () => { it("should format correclty date", () => { const date = new Date("2023-11-02"); expect(shortDate(date)).toEqual("2023-11-02"); }); }); describe("shortDate", () => { it("should shorten long text at 50 chars", () => { expect( ellipsis( "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a faucibus massa." ) ).toEqual("Lorem ipsum dolor sit amet, consectetur adipiscing…"); }); it("should leave short text unchanged", () => { expect(ellipsis("Lorem ipsum sin dolor")).toEqual( "Lorem ipsum sin dolor" ); }); it("should shorten to custom length", () => { expect(ellipsis("Lorem ipsum sin dolor", 10)).toEqual("Lorem ipsu…"); }); }); describe("translate", () => { it("should translate to supported langauges", () => { expect(translate("hello", "en")).toEqual("Hello!"); expect(translate("hello", "pl")).toEqual("Cześć!"); }); }); describe("applyDiscount", () => { it("should lower the price accordingly", () => { expect(applyDiscount(120, 25)).toEqual(90); expect(applyDiscount(8, 50)).toEqual(4); }); }); describe("calculatePrice", () => { it("should find a price of many products", () => { expect(calculatePrice(4, 3)).toEqual(12); expect(calculatePrice(9, 0.5)).toEqual(4.5); }); }); });

(文件spec/main.spec.js

运行测试

要运行测试,我们可以将以下脚本添加到package.json

 .. "scripts": { "test": "jasmine" }, …


完成此操作后, npm run test运行我们的测试:

 $ npm run test > [email protected] test > jasmine Randomized with seed 76873 Started ........ 8 specs, 0 failures Finished in 0.004 seconds Randomized with seed 76873 (jasmine --random=true --seed=76873)

概括

在这篇文章中,我们了解了一个简单的 JS 代码示例以及如何通过单元测试覆盖它。您可以在 GitHub 上找到完整的代码示例


也发布在这里