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

测试工具 创建于:2022-06-12
  
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"); });

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


  
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理

权威发布,测试选择不纠结!第15届软件测试行业报告,直击行业发展,把握未来方向!

原文地址:http://www.51testing.com/?action-viewnews-itemid-5002322

免责声明:本文来源于互联网,版权归合法拥有者所有,如有侵权请公众号联系管理员

* 本站提供的一些文章、资料是供学习研究之用,如用于商业用途,请购买正版。

发表于:2022-5-30 09:16 作者:三年没洗澡 来源:掘金