一、什么是单元测试

在维基百科上搜索unit test会看到这段话:

In computer programming, unit testing is a software testing method by which individual units of source code—sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures—are tested to determine whether they are fit for use.

翻译:在计算机编程中,单元测试是一种软件测试方法,通过这种方法,对一个或多个计算机程序模块的源代码集的各个单元以及相关的控制数据、使用程序和操作程序进行测试,以确定它们是否适合使用。

这是Kolawa Adam在 Automated Defect Prevention: Best Practices in Software Management 一书中对单元测试的定义。结合百度百科写的,单元测试是指对软件中的最小可测试单元进行检查和验证。对于前端来说,就是通过编写完备的测试用例,来测试可测的函数,保证函数在各种情况下都能如期执行。

二、 相关概念

1、白盒测试和黑盒测试
白盒测试又称结构测试,即对程序内部的逻辑做细致性的测试,代码走查、单元测试等均属于白盒测试。
黑盒测试又称功能测试,即在不考虑内部实现的基础上对各个功能模块进行测试,主要测试接口能否跑通,功能是否正常。

2、TDD(Test-Driven Development)
测试驱动开发应有如下几个原则:
1)Add a test
在代码添加一个新特性之前需要先编写一个测试,这使得开发人员在编写代码之前就关注需求。这与通常的做法不同,如单元测试一般是在代码编写完成之后进行。
2)Run all tests. The new test should fail for expected reasons
运行所有测试,按预期新增的测试会失败。这证明了新的功能需要新的代码来完成。
3)Write the simplest code that passes the new test
编写最简单、最易于理解的代码来通过所有的测试。在这个阶段我们不用考虑代码是否是最优雅的或者性能最高的,只要通过测试即可。
4)Refactor as needed, using tests after each refactor to ensure that functionality is preserved
重构代码,让代码具有更高的可读性、可维护性。重构之后必须保证所有测试同样通过。
5)Repeat
每次添加新功能时均重复以上流程。测试应是小型的、增量的,避免出现测试不通过时大量修改代码的情况。

3、BDD(Behaviour-Driven Development)
行为驱动开发即通过使用简单的领域特定语言使用自然语言结构来表达行为和预期的效果。大部分BDD软件工具遵循以下流程:

  • Scenario(场景),说明功能的例子
  • Given(假如),构造测试的环境条件
  • When(当),给予的输入,可以是用户,也可以是外部系统,也可以是系统本身定时/条件触发的
  • Then(那么),系统的输出,或者说行为

若干个Given,When,Then构成一个Scenario,若干个Scenario构成一个Feature,若干个Feature最终构成一个系统的完整功能需求。

4、ATDD(Acceptance Test-Driven Development)
验收测试驱动开发与BDD非常相似,如果说BDD是让除开发外的人了解需求,那ATDD则是更加细化需求,如测试工程师编写测试用例提供给开发用于冒烟。

总结一下:通常单元测试的时机在于代码编写完成之后,这意味着测试的粒度与TDD相比更加“粗”一点,需要关注的边界条件更加多,测试用例更加复杂,但好处就是效率是要更高的。

三、测试框架Jest

背景:测试typescript编写的react代码。

1、安装依赖,其中jest是基础库,@types/jest提供了类型提示(可以使用官方包@jest/types代替,使用稍麻烦),ts-jest提供了检测ts代码的能力。

yarn add -D jest @types/jest ts-jest

2、生成 jest.config.js 文件

yarn ts-jest config:init

3、将如下代码添加到 package.json 中:

{
  "scripts": {
    "test": "jest"
  }
}

4、编写测试用例后,运行 yarn test

/**
 * util.ts
 * 编写一个加法函数
 */
export const add = (a: number, b: number) => {
  return a + b
}
/**
 * __test__/util.test.ts
 * 编写测试用例
 */
import { add } from '../util'

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

test('adds -1 + 2 to equal 1', () => {
  expect(add(-1, 2)).toBe(1);
});

test('adds 2 + 3 to equal 5', () => {
  expect(add(2, 3)).toBe(5);
});

运行 yarn test 后的结果为:

JTest静态分析工具 “jtest”_JTest静态分析工具


在大部分情况下,我们只想为新增的页面或者文件跑case,我们可以用命令 yarn test fileName [-t caseName],例如:

yarn test util.test.ts -t 'adds 1 \+ 2 to equal 3'

结果如下:

JTest静态分析工具 “jtest”_javascript_02


每次敲一行代码略显麻烦,vscode可以安装 Jest Runner 这个插件,安装之后执行单个用例或单个文件极为方便:

JTest静态分析工具 “jtest”_测试框架_03


Jest框架的具体使用可以去官网进一步学习,目前写了四篇笔记 ➘➘➘。

一、Jest测试框架入门之匹配器与测试异步代码二、Jest测试框架入门之四个钩子及分组三、Jest测试框架入门之Mock四、Jest测试框架入门之快照测试(附踩坑指南)