多测师是一家拥有先进的教学理念,强大的师资团队,业内好评甚多的接口自动化测试培训机构!

17727591462

联系电话

您现在所在位置:接口自动化测试培训 > 新闻资讯

前端自动化测试框架Jest中的钩子函数及作用域

更新时间:2022-06-08 09:21:03 作者:多测师 浏览:131

  Jest 中的钩子函数

  通常,在编写测试时,你需要在测试运行之前进行一些初始化工作,并且需要在测试运行之后进行一些完成工作。Jest提供了钩子函数来处理这个问题。我们通过一个计数器来学习钩子函数相关的知识。

前端自动化测试框架Jest中的钩子函数及作用域

  首先在index.js里面定义一个类,并且导出:

  // index.js

  class Counter {

  constructor() {

  this.number = 0;

  }

  add() {

  this.number++;

  }

  minus() {

  this.number--;

  }

  }

  export default Counter;

  可以看到,这是一个使用 ES6 语法定义的 class:

  在实例化的时候定义了number,初始值是0

  定义了静态方法add,执行结果为number加1

  定义了静态方法minus,执行结果为number减1

  然后在index.test.js里面引入这个类,测试add方法:

  // index.test.js

  import Counter from "./index";

  const counter = new Counter();

  test("测试 Counter 的 add 方法", () => {

  expect(counter.number).toBe(0);

  counter.add();

  expect(counter.number).toBe(1);

  });

  然后运行测试用例,完美通过。

  然后继续添加minus方法的测试用例:

  // index.test.js

  import Counter from "./index";

  const counter = new Counter();

  test("测试 Counter 的 add 方法", () => {

  expect(counter.number).toBe(0);

  counter.add();

  expect(counter.number).toBe(1);

  });

  test("测试 Counter 的 minus 方法", () => {

  expect(counter.number).toBe(0);

  counter.minus();

  expect(counter.number).toBe(-1);

  });

  然后运行测试用例,结果为:

  测试 add 方法:通过

  测试 minus 方法:不通过

  出现这个情况的原因是:

  我们的实例化过程写在了测试用例外面,所有的测试用例公用一个counter 实例,所以在测试 add 方法的时候,我们已经对实例的number属性做出了修改。导致minus方法的测试用例没用通过。

  解决办法是:

  我们可以把实例化写在每一个测试用例里面,每次测试都创建一个新的counter 实例。这样就不会公用一个counter了,也不会影响到其它实例了。

  但是一般情况下,我们不会这样做,因为测试用例很多的话,每次都创建一个 counter实例 是一件很麻烦的事情,假如当前文件中有1000个和counter有关的测试用例,那么就要创建1000次counter实例。

  这个时候!钩子函数派上用场了!

  // index.test.js

  import Counter from "./index";

  let counter = null;

  beforeEach(() => {

  counter = new Counter();

  });

  test("测试 counter 的 add 方法", () => {

  expect(counter.number).toBe(0);

  counter.add();

  expect(counter.number).toBe(1);

  });

  test("测试 counter 的 minus 方法", () => {

  expect(counter.number).toBe(0);

  counter.minus();

  expect(counter.number).toBe(-1);

  });

  然后运行测试用例,结果通过。

  beforeEach() 的作用是在每个测试用例执行之前执行里面的回调函数,如果你需要在测试开始之前对很多个测试做一些重复的工作,比如要初始化状态,你就可以使用它。

  实际上,Jest 一共有四个钩子函数:

  beforeAll:在所有测试用例执行之前调用(调用一次)

  afterAll:在所有测试用例执行之后调用(调用一次)

  beforeEach:在每个测试用例执行之前调用(调用多次)

  afterEach:在每个测试用例执行之后调用(调用多次)

  钩子函数的作用域

  在了解作用域之前,需要先了解一个小知识点:Scoping

  默认情况下,beforeAll和afterAll应用于文件中的每个测试用例。

  实际上,还可以使用describe方法将测试用例进行分组。当它们位于describe中时,beforeAll和afterAll只应用于当前分组中的测试用例。

  // index.test.js

  describe("测试分组1", () => {

  beforeAll(() => {

  console.log("测试分组1 - beforeAll");

  });

  afterAll(() => {

  console.log("测试分组1 - afterAll");

  });

  test("测试", () => {

  console.log("测试分组1 测试");

  expect(1 + 1).toBe(2);

  });

  });

  describe("测试分组2", () => {

  beforeAll(() => {

  console.log("测试分组2 - beforeAll");

  });

  afterAll(() => {

  console.log("测试分组2 - afterAll");

  });

  test("测试", () => {

  console.log("测试分组2 测试");

  expect(1 + 1).toBe(2);

  });

  });

  在默认情况下,Jest将按照describe的顺序连续运行所有测试分组,等待每个测试完成后再继续。

  需要注意的是:

  如果我们不进行分组,相当于在最外面写了一层describe。

  除此之外,实际上,在describe里面还能嵌套describe,就像下面这样:

  // index.test.js

  describe("第一层", () => {

  beforeAll(() => console.log("第一层 - beforeAll"));

  describe("第二层", () => {

  beforeAll(() => console.log("第二层 - beforeAll"));

  describe("第三层", () => {

  beforeAll(() => console.log("第三层 - beforeAll"));

  test("测试", () => {

  console.log("测试");

  expect("hello" + " " + "world").toBe("hello world");

  });

  });

  });

  });

  所以可以得出一些结论:

  每一个 describe 都可以有自己的钩子函数

  每一个 describe 都有自己的作用域

  每一个 钩子函数也有自己的作用域,就是当前所在的 describe

  每一个 describe 里面的钩子函数对自己作用域下面所有的测试用例都生效

  如果 describe 是多层嵌套的,那么测试用例执行的顺序是由外到内

  最后再补充一个知识点:

  如果有·、多个测试用例,但是只想运行一个的时候,注释掉其它的测试用例往往不是最好的选择,我们可以使.only语法去执行:

  // index.test.js

  test.only("这个测试会被执行", () => {

  expect("A").toBe("A");

  });

  test("这个测试会被跳过", () => {

  expect("B").toBe("B");

  });

  这样就可以单独运行一个测试用例,其它测试会被跳过。

  以上内容为大家介绍了前端自动化测试框架Jest中的钩子函数及作用域,本文由多测师亲自撰写,希望对大家有所帮助。了解更多自动化测试相关知识:https://www.aichudan.com/xwzx/

联系电话

17727591462

返回顶部