JS 单元测试简介
为什么要测试?
测试种类
术语
单元测试
笑话
摩卡
茉莉花
磁带
AVA
实习生
Cucumber.js
测试,测试……
这篇文章取自我的博客,所以一定要查看它以获取更多最新内容😉
如果您是编程新手,或者只是个业余程序员,从未参与过任何开源项目,那么您可能会对测试代码的想法有些怀疑。如果确实如此,那么在本文中,我将说服您,对代码进行单元测试并进行测试通常是一个值得遵循的良好做法。然后,我们将学习/复习一些关于代码测试的知识,最后探索进行单元测试的最佳工具。尽情享受吧!😉
为什么要测试?
首先,我们来谈谈测试的重要性。开发任何类型的应用程序或工具(尤其是开源工具)时,测试都是您的得力助手。想想测试能带来的质量提升。当测试涵盖代码中所有可能的异常和情况时,您就可以确保将来不会出错。这又是测试的另一个原因——保证。对整个代码库进行测试并保持更新,可以让您持续检查是否存在任何错误。这可以确保一切正常。如果您没有做过需要多人管理或服务于他人(OSS)的项目,那么您可能不会真正重视这种保证。但相信我,这真的很重要。如果没有任何保证,您永远无法确保代码的完整性。😕 最后但并非最不重要的是,我们拥有文档的优势。信不信由你,正确完成的测试有时比整页文本更能帮助您理解如何使用特定的代码段。试想一下。你的代码已经通过了测试。这样,你就掌握了如何使用给定代码以及其结果是什么的信息。所以,正如你所见,有很多理由开始测试你的代码,所以如果你还没有开始,现在是时候开始测试了!
测试种类
如果我能说服你开始做测试,那我真的很高兴。🎉 但是,代码测试的世界如此广阔,一开始可能会让人感到有些不知所措。有太多的术语、概念、思想、工具和库需要了解。那么,让我们先来梳理一下。首先,你必须知道你正在进行哪种类型的测试,这样你才能选择合适的工具来完成这项工作。测试主要分为三种类型,根据它们存在的原因来划分。
- 单元测试- 单元测试允许你测试代码中非常具体的方面,例如,测试某个函数是否符合预期结果。这时,测试覆盖所有代码至关重要,要逐个功能地覆盖所有功能。这是本文的重点。
- 集成测试- 测试代码的不同部分(例如组件)是否正常工作。您还应该检查它们协同工作的方式,即结构完整性。检查副作用也非常重要。您必须知道是否存在任何您未计划的函数调用等。
- 功能测试——我认为UI 测试这个名字更能解释其用途。功能测试是指在特定环境(通常是浏览器)中测试最终产品(例如 Web 应用)。这里引入了无头浏览器的概念,即通过调用不同的 API 控制浏览器,在没有可见 UI 的浏览器中执行测试。乍一看可能有点别扭,但它是一项非常有用的技术,尤其可以节省 UI 和其他流程所需的时间,而这些流程在无头模式下是不存在的。
术语
现在,您对不同类型的测试以及单元测试到底是什么有了更多的了解,我认为谈论一下测试的基本概念和术语是个好主意。
首先,我想解释一下TDD和BDD 的捷径,你可能之前在某个地方见过,但没怎么留意。这些捷径可以作为构建和编写测试的基本准则。
测试驱动开发(简称 TDD)是一种基于测试进行软件开发的过程。它就像一个循环——每次你想添加一个功能时,你首先要编写测试(此时测试显然会失败),然后编写满足这些测试的实际代码,最后再次进行测试以验证这一点。你的开发是基于测试的。这个想法很有意思,你不觉得吗?
至于行为驱动开发(BDD),它又是另一种意识形态,实际上是基于 TDD 的。但是,这个名字可能不像第一个那样不言自明。它可以被看作是 TDD,但有一些更好的附加指导方针。在这里,我们的开发不是由测试驱动的,而是由行为、规范驱动的,实际上它们也是测试。😂 只是用纯英语描述得更好。这使您的测试有更好的文档记录,从而更具可读性。这就是为什么图书馆比 TDD 更频繁地采用这种测试方式的原因。
了解了这两个在测试中非常重要的趋势后,是时候探索一些术语了,正如 BDD 所建议的那样,用英语进行解释。😉
- 断言函数——我们用来测试代码是否符合预期输出的函数。在 Jest 和许多其他单元测试库中,它们如下所示:
expect(value).toBeTruthy()
- 代码覆盖率- 表明测试覆盖了代码的多少部分。这些统计数据非常有用,在选择下一个测试库时可以作为附加功能考虑。当然,有一些独立的工具可以实现这一点,但将所有功能都放在一个包中会更方便。
- 环境- 通常是一个(无头)浏览器或类似的工具,用于功能测试。我们不会深入探讨这个,但这里也有一些不错的选择。😄
- 模拟(也称为伪造)用于伪造某些行为以便稍后在测试中使用它们,即使没有以现实的方式实现不同的功能也能提供可靠的输入/输出检查。
- 间谍- 提供有关函数的信息。通过它们,您可以了解函数被调用的次数、调用时间以及调用参数。它们可能是检查副作用的最佳方法。
- 存根(Stubs) ——或者称为配音(dubs),使您能够用不同的东西替换所选的功能,以测试预期的功能和行为。
- 快照测试- 一种测试方法,基于将输出数据与已保存的副本(快照)进行比较。
至此,您应该对所选库的测试方法和功能有了基本的了解。由于这里我仅关注单元测试,请务必查看上面列出的一些链接,了解在独立包中提供特定功能的工具。
单元测试
理论讲完了,是时候开始测试了——单元测试!但首先,让我们选择最适合这项工作的工具。以下列出了一些用于单元测试及其他用途的最佳库和工具。🔥
笑话
test('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
说到单元测试,Jest是我的首选。它由 Facebook 的几位成员创建,并已与许多流行库(例如React本身)进行了充分的测试。它几乎提供了高质量单元测试所需的所有功能。易读的断言函数、出色的覆盖率报告、模拟 API、并行测试运行器以及总体易用性,使这个库成为目前市场上最好的选择之一,尤其是在 BDD 领域。除此之外,它还拥有强大的社区和支持,以及编写精良的文档。
摩卡
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1,2,3].indexOf(4), -1);
});
});
});
Mocha是另一个库,其目标是使测试变得有趣和简单。遵循 BDD 思想,它具有精心设计的描述性 API。此外,Mocha 在架构方面也有所不同。它为开发人员提供了最小、灵活的设置,允许他们使用其他自定义库进行扩展,负责不同的任务。使用 Mocha,您可以使用任何您想要的断言库(它没有自己的断言库),包括 NodeJS 内置或Chai。它的 API 可能感觉与 Jest 有点相似,但有一些细微的差别。由于它的架构,Mocha 缺少 Jest 内置的功能。我们谈论的是代码覆盖率,更重要的是并行测试运行器(Mocha 仅在一个进程上运行测试)。好吧,在功能不足的地方,Mocha 通过多种测试进度报告器(Jest 也支持此功能)在视觉效果上弥补了这一点。但是,正如我所说,Mocha 适合那些喜欢拥有自己可配置设置的人。除此之外,它的文档可能感觉不如 Jest 的文档那么精致,但它们肯定详尽地讨论了该主题。
茉莉花
describe("A suite is just a function", function() {
var a;
it("and so is a spec", function() {
a = true;
expect(a).toBe(true);
});
});
Jasmine可能比此列表中的一些竞争对手更老一些。它标榜自己功能齐全,力求提供开发人员可能需要的所有功能。因此,Jasmine 内置了断言功能,并实现了类似 expect 的风格。此外,它还内置了其他功能,例如间谍、模拟、报告等。此外,如果您使用Ruby或Python进行开发,您可能会发现使用相同的库会更方便,因为 Jasmine 官方支持这两个库。至于文档,它们涵盖了所有主题,但其结构并没有给我留下深刻的印象。
磁带
var test = require('tape');
test('timing test', function (t) {
t.plan(1);
var start = Date.now();
setTimeout(function () {
t.equal(Date.now() - start, 100);
}, 100);
});
Tape是一个极简且灵活的 NodeJS 和浏览器测试库。它的 API 与其他库略有不同,但仍然易于理解,并且秉承相同的理念。所有你需要了解的信息都包含在一个README 文件中。而且……它对大量TAP报告器提供了良好的支持,这始终是一个优势。
AVA
import test from 'ava';
test('foo', t => {
t.pass();
});
test('bar', async t => {
const bar = Promise.resolve('bar');
t.is(await bar, 'bar');
});
AVA是一个内置断言函数的测试库,专注于异步测试。它拥有简洁的 API(与其他 BDD 工具类似),并支持并行运行测试。与 Tape(其灵感来源)类似,它没有隐式全局变量。此外,它内置了 Babel v7,因此您无需任何额外配置即可使用 ES-Next 编写测试。所有文档均可在其 GitHub 仓库中找到。
实习生
Intern是一个 TDD/BDD 测试框架,也是 JavaScript 和 TypeScript 的测试运行器。它允许您执行单元测试和功能测试。它使用Chai作为断言库,并使用Istanbul生成代码覆盖率统计数据。它还可以并发运行测试。总的来说,它是一个可扩展的测试框架。我有没有提到过,它有非常完善、全面的文档?
Cucumber.js
Feature: Simple maths
In order to do maths
As a developer
I want to increment variables
Scenario: easy maths
Given a variable set to 1
When I increment the variable by 1
Then the variable should contain 2
Scenario Outline: much more complex stuff
Given a variable set to <var>
When I increment the variable by <increment>
Then the variable should contain <result>
Examples:
| var | increment | result |
| 100 | 5 | 105 |
| 99 | 1234 | 1333 |
| 12 | 5 | 18 |
Cucumber.js是另一个单元测试工具,但这次略有不同……它允许你用通俗易懂的语言编写测试。基本上,你需要使用一些关键字(例如Scenario、Given、When等)以结构化的文本格式编写测试,然后在代码中定义每个用通俗易懂的语言编写的步骤,以运行预期的测试。我从未使用过这种方法,所以无法告诉你它在实际使用中有多方便。但至少看起来很有趣。😅
测试,测试……
好了,这就是我列出的单元测试最佳工具清单。当然,如果我遗漏了任何值得添加到清单中的工具,请在评论区告诉我。请注意,我在此清单中仅涵盖了单元测试,因此不包含集成、功能或端到端(涵盖所有类型的测试)测试工具。我认为一篇文章涵盖的内容太多了。依我之见,最好逐一探讨一些较小的主题。事实上,通过阅读那篇文章,我也学到了很多东西。我当然不是测试专家,但至少现在我获得了一些新知识。希望这篇文章也能帮助你踏上代码测试之旅。目前就这些。如果你喜欢那篇文章,请务必偶尔查看我的博客,并在 Twitter和Facebook 上关注我。✌
文章来源:https://dev.to/areknawo/introduction-to-unit-testing-in-js-2bmk