Skip to content

Latest commit

 

History

History
99 lines (61 loc) · 3.93 KB

测试规范.md

File metadata and controls

99 lines (61 loc) · 3.93 KB

在开始聊测试规范之前,如果你还在写测试这件事情上苦苦挣扎,可以瞅瞅我的 另一个仓库 我会在这个仓库中慢慢整理我在项目中遇到的,大家都很苦恼的一个测试场景,目的是为了让大家有作业可以抄。

技术栈

这里的测试规范我想先聚焦于单元测试,如果后面机会再扩展到诸如 UI、E2E 之类的更高层级的测试规范。而技术栈我会默认是常规的 Jest + React Testing Library + React Testing Library/React Hooks。但是理论上这些规范都可以扩展到不同的技术栈当中去,重要的是思想。

测试文件位置

首先也是我们之前有提到过的,测试文件应该位于被测文件同级目录下的 __tests__ 目录下,以便于快速定位两个相联文件的位置。

测试层级

在测试时你的所有测试应该被一个最外层的 describe 表达式包裹,这个 describe 的第一个字符串参数应该是 '#' 加你将要测试的文件名。用以告知读代码的人这是这个测试的最外层。

如果你的文件中有多个独立的方法需要测试(这种情况一般出现在 utils/helpers 文件中)那么你应该使用第二层 describe 将每一个待测方法的测试用例包裹起来,这时当前这个 describe 的字符串参数应该是 '##' 加你将要测试的方法名,下面是一个没什么意义的简单的例子。

describe("# utils", () => {
  describe("## isSomeFiledsRequired", () => {
    it("should return false when input is false", () => {
        expect(isSomeFiledsRequired(false)).toBeFalsy();
      },
    );
    
    it("should return true when input is true", () => {
        expect(isSomeFiledsRequired(true)).toBeTruthy();
      },
    );
  });
  
  describe("## isSomeFiledsOptional", () => {
    it("should return false when input is false", () => {
        expect(isSomeFiledsOptional(false)).toBeFalsy();
      },
    );
    
    it("should return true when input is true", () => {
        expect(isSomeFiledsOptional(true)).toBeTruthy();
      },
    );
  });
});

这样分级的意义在于如果你的文件中有多个方法时,你的测试将更加可读,能够一眼看出你的每一个方法的测试在哪里,便于修改和管理。

测试用例描述

每一个测试用例应该拥有有可读性强的用例描述,同时为了统一用例描述,我们推荐你采用如下的用例描述格式:

should xxxxx given xxxxxx when xxxxxx

根据不同的场景 given 的部分可以省略,这样的句式能够让看测试的人快速明白这个测试用例的目的是什么,条件是什么。可以结合用例的代码快速理解整个测试用例的目的。

测试用例模式

每一个测试用例在编写的时候不应该包含任何逻辑,只应该调用目标函数/组件,然后对它们的输出进行断言。

其次每一个测试用例都应该遵循 given when then 的原则,并且在某一个步骤超过三行的情况下添加注释

  1. 准备好被测函数/组件需要的输入/mock
  2. 调用目标函数/组件
  3. 对它们的输出进行断言
it("should return xxx given yyy is zzz when is some business case", () => {
  // given
  const param1 = { a: 1, b: 2 };
  const param2 = jest.fn();
  const param3 = jest.fn();
  const param4 = "dididi";
  
  // when
  const result = Foo({ param1, param2, param3, param4 });
  
  // then
  expect(result).toBe("lalala");
  expect(param2).toBeCalledWith("biubiubiu");
  expect(param3).toBeCalledTimes(2);
});

参数化测试

如果你的多个测试仅仅是为了测试某个方法/组件在不同参数下的不同输出,请使用 参数化测试 来简化你的测试。

这不但可以让你的测试用例更加简洁,也能够让代码阅读者更容易理解你的测试。