您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

前端测试框架Jest——语法篇

时间:2020-06-23 15:14:27  来源:  作者:

使用匹配器

使用不同匹配器可以测试输入输出的值是否符合预期。下面介绍一些常见的匹配器。普通匹配器最简单的测试值的方法就是看是否精确匹配。首先是toBe()

test('two plus two is four', () => {
  expect(2 + 2).toBe(4);
});

toBe用的是JAVAScript中的Object.is(),属于ES6中的特性,所以不能检测对象,如果要检测对象的值的话,需要用到toEqual。toEquel递归检查对象或者数组中的每个字段。

test('object assignment', () => {
  const data = {one: 1};
  data['two'] = 2;
  expect(data).toEqual({one: 1, two: 2});
});

Truthiness

在实际的测试中,我们有时候需要区分undefined、null和false。以下的一些规则有助于我们进行。

  • toBeNull只匹配null
  • toBeUndefined只匹配undefined
  • toBeDefine与toBeUndefined相反
  • toBeTruthy匹配任何if语句为真
  • toBeFalsy匹配任何if语句为假

数字匹配器

大多数的比较数字有等价的匹配器。

  • 大于。toBeGreaterThan()
  • 大于或者等于。toBeGreaterThanOrEqual()
  • 小于。toBeLessThan()
  • 小于或等于。toBeLessThanOrEqual()
  • toBe和toEqual同样适用于数字 注意:对比两个浮点数是否相等的时候,使用toBeCloseTo而不是toEqual

例子如下:

test('two plus two', () => {
  const value = 2 + 2;
  expect(value).toBeGreaterThan(3);
  expect(value).toBeGreaterThanOrEqual(3.5);
  expect(value).toBeLessThan(5);
  expect(value).toBeLessThanOrEqual(4.5);

  // toBe and toEqual are equivalent for numbers
  expect(value).toBe(4);
  expect(value).toEqual(4);
});
test('两个浮点数字相加', () => {
  const value = 0.1 + 0.2;
  //expect(value).toBe(0.3);           这句会报错,因为浮点数有舍入误差
  expect(value).toBeCloseTo(0.3); // 这句可以运行
});

如果使用toBe就会产生以下结果:

前端测试框架Jest——语法篇

 

字符串

使用toMatch()测试字符串,传递的参数是正则表达式。

test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});

test('but there is a "stop" in Christoph', () => {
  expect('Christoph').toMatch(/stop/);
});

数组

如何检测数组中是否包含特定某一项?可以使用toContain()

const shoppingList = [
  'diapers',
  'kleenex',
  'trash bags',
  'paper towels',
  'beer',
];

test('购物清单(shopping list)里面有啤酒(beer)', () => {
  expect(shoppingList).toContain('beer');
});

另外

如果你想在测试特定函数的时候抛出一个错误,在它调用的时候可以使用toThrow。

function compileAndroidCode() {
  throw new ConfigError('you are using the wrong JDK');
}

test('compiling android goes as expected', () => {
  expect(compileAndroidCode).toThrow();
  expect(compileAndroidCode).toThrow(ConfigError);

  // You can also use the exact error message or a regexp
  expect(compileAndroidCode).toThrow('you are using the wrong JDK');
  expect(compileAndroidCode).toThrow(/JDK/);
});

测试异步代码

在实际开发过程中,我们经常会遇到一些异步的JavaScript代码。当你有以异步方式运行的代码的时候,Jest需要知道当前它测试的代码是否已经完成,然后它可以转移动另一个测试。也就是说,测试用例一定要在测试对象结束之后才能够结束

为了达到这一目的,Jest有多种方法可以做到。

回调

最常见的异步模式就是回调函数。

注意:回调函数和异步没有必然的联系,回调只是异步的一种调用方式而已,不要将异步和回调两个概念结合起来谈

比如以下代码:

// 这里是同步执行的,完全没有异步
function fun1(callback) {
  callback();
}

现在假设一个fetchData(call)函数,获取一些数据并在完成的时候调用call(data),而我想要测试返回的数据是不是字符串'peanut butter'

默认情况下,一旦到达运行上下文底部,jest测试就会立即结束。这意味着这个测试将不能按照预期的进行。

function fetchData(call) {
  setTimeout(() => {
    call('peanut butter1')
  },1000);
}

test('the data is peanut butter', () => {
  function callback(data) {
    expect(data).toBe('peanut butter'); // 这里没有执行到
    // done()
  }
  fetchData(callback);
});

这样做是不会报错的,因为没有执行到我们想要测试的语句中的时候Jest测试已经结束了。(一旦fetchData执行结束,此测试就在没有调用回调函数前结束,因为使用了setTimeout,产生了异步)

而我们可以改成以下: 使用单个参数调用done,而不是将测试放在一个空参数的函数中,Jest会等done回调函数执行结束后,结束测试。

function fetchData(call) {
  setTimeout(() => {
    call('peanut butter1')
  },1000);
}

test('the data is peanut butter', (done) => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done()
  }
  fetchData(callback);
});
前端测试框架Jest——语法篇

 

如果done()永远不会被调用,则说明这个测试将失败,这也正是我们所希望看到的。

Promise

如果我们的代码中使用到了Promises,只需要从你的测试中返回一个Promise,Jest就会等待这个Promise来解决。如果承诺被拒绝,则测试将会自动失败。

举个例子,如果fetchData,使用Promise代替回调的话,返回值是应该解析为一个字符串'peanut butter'的Promise。那么我们可以使用以下方式进行测试代码:

test('the data is peanut butter', () => {
  expect.assertions(1);
  return fetchData().then(data => {
    expect(data).toBe('peanut butter');
  });
});

注意:一定要返回Promise,如果省略了return语句,测试将会在fetchData完成之前完成。

另外一种情况,就是想要Promise被拒绝,我们可以使用.catch方法。另外,要确保添加了expect.assertions来验证一定数量的断言被调用。否则一个fulfilled态的Promise不会让测试失败。

test('the fetch fails with an error', () => {
  expect.assertions(1);
  return fetchData().catch(e => expect(e).toMatch('error'));
});

.resolves/.rejects

可以使用./resolves匹配器匹配你的期望的声明(跟Promise类似),如果想要被拒绝,可以使用.rejects

test('the data is peanut butter', () => {
  expect.assertions(1);
  return expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', () => {
  expect.assertions(1);
  return expect(fetchData()).rejects.toMatch('error');
});

Async/Await

若要编写async测试,只要在函数前面使用async关键字传递到test。比如,可以用来测试相同的fetchData()方案

test('the data is peanut butter', async () => {
  expect.assertions(1);
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});

test('the fetch fails with an error', async () => {
  expect.assertions(1);
  try {
    await fetchData();
  } catch (e) {
    expect(e).toMatch('error');
  }
});

setup and teardown

写测试的时候,我们经常需要进行测试之前做一些准备工作,和在进行测试后需要进行一些整理工作。Jest提供辅助函数来处理这个问题。

为多次测试重复设置

如果你有一些要为多次测试重复设置的工作,可以使用beforeEach和afterEach。

有这样一个需求,需要我们在每个测试之前调用方法initializeCityDatabase(),在每个测试后,调用方法clearCityDatabase()

beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

一次性设置

在某些情况下,你只需要在文件的开头做一次设置。这种设置是异步行为的时候,你不太可能一行处理它。Jest提供了beforeAll和afterAll处理这种情况。

beforeAll(() => {
  return initializeCityDatabase();
});

afterAll(() => {
  return clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

作用域

默认情况下,before和after的块可以应用到文件中的每一个测试。此外可以通过describe块来将将测试中的某一块进行分组。当before和after的块在describe块内部的时候,则只适用于该describe块内的测试。

比如说,我们不仅有一个城市的数据库,还有一个食品数据库。我们可以为不同的测试做不同的设置︰

// Applies to all tests in this file
beforeEach(() => {
  return initializeCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

describe('matching cities to foods', () => {
  // Applies only to tests in this describe block
  beforeEach(() => {
    return initializeFoodDatabase();
  });

  test('Vienna <3 sausage', () => {
    expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
  });

  test('San Juan <3 plantains', () => {
    expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
  });
});

注意:顶级的beforeEach描述块内的beforeEach之前执行,以下的例子可以方便我们认识到执行的顺序

beforeAll(() => console.log('1 - beforeAll'));
afterAll(() => console.log('1 - afterAll'));
beforeEach(() => console.log('1 - beforeEach'));
afterEach(() => console.log('1 - afterEach'));
test('', () => console.log('1 - test'));
describe('Scoped / Nested block', () => {
  beforeAll(() => console.log('2 - beforeAll'));
  afterAll(() => console.log('2 - afterAll'));
  beforeEach(() => console.log('2 - beforeEach'));
  afterEach(() => console.log('2 - afterEach'));
  test('', () => console.log('2 - test'));
});

// 1 - beforeAll
// 1 - beforeEach
// 1 - test
// 1 - afterEach
// 2 - beforeAll
// 1 - beforeEach  //特别注意
// 2 - beforeEach
// 2 - test
// 2 - afterEach
// 1 - afterEach
// 2 - afterAll
// 1 - afterAll

以上内容就是本篇的全部内容以上内容希望对你有帮助,有被帮助到的朋友欢迎点赞,评论。



Tags:测试框架   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
Hello 大家好,我是阿粉,日常工作中很多时候我们都需要同事间的相互配合协作完成某些功能,所以我们经常会遇到服务或者应用内不同模块之间要互相依赖的场景。比如下面的场景,...【详细内容】
2021-06-09  Tags: 测试框架  点击:(127)  评论:(0)  加入收藏
近期准备优先做接口测试的覆盖,为此需要开发一个测试框架,经过思考,这次依然想做点儿不一样的东西。 接口测试是比较讲究效率的,测试人员会希望很快能得到结果反馈,然而接口的数...【详细内容】
2021-04-01  Tags: 测试框架  点击:(210)  评论:(0)  加入收藏
先来个小故事:一天,你的领导丢给你几十个接口,然后希望你输出报告。你:"exm?",改改改。于是你引入了unittest单元测试框架、HTMLTestRunner等等。正打算将各个测试用例分类重新规...【详细内容】
2020-11-04  Tags: 测试框架  点击:(113)  评论:(0)  加入收藏
一、背景近年来,随着银行业业务品种的激增,各应用系统也日益增多,各应用系统关系错综复杂,支系繁多。缺乏科学的方法来快速明确业务需求所指向的应用系统,导致测试过程中出现覆盖...【详细内容】
2020-10-22  Tags: 测试框架  点击:(118)  评论:(0)  加入收藏
应用场景:在API的测试中,测试某些具体数据值,比如返回的结果是否是需求的类型,文件是否是符合且具备完整的数据结构。这些都是必须且很细致的测试工作。另外,组织、运行测试场景,...【详细内容】
2020-10-19  Tags: 测试框架  点击:(244)  评论:(0)  加入收藏
我们在测试时,可能会遇到以下几种测试分组的场景: 一个测试类当中有多个测试方法,只想执行其中的几个相关的测试方法。 当几个相关的方法依赖相同的 setUp、tearDown操作。 ...【详细内容】
2020-07-26  Tags: 测试框架  点击:(37)  评论:(0)  加入收藏
萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI想要清理文件夹内部分冗余文件,结果误删了同事刚合的代码?(例如,在rm -rf /usr/bin/test的/usr后面加了个空格,结果删掉了整个/usr...【详细内容】
2020-07-20  Tags: 测试框架  点击:(62)  评论:(0)  加入收藏
使用匹配器使用不同匹配器可以测试输入输出的值是否符合预期。下面介绍一些常见的匹配器。普通匹配器最简单的测试值的方法就是看是否精确匹配。首先是toBe()test(&#39;two...【详细内容】
2020-06-23  Tags: 测试框架  点击:(83)  评论:(0)  加入收藏
在 UI 自动化测试过程中,面对复杂的业务场景,经常会遇到这样的挑战: 简单的录制/回放速度快,但无法适应复杂场景; 编写自动化测试脚本比较灵活,但工作量大且可维护性差; 以往的封装...【详细内容】
2020-06-18  Tags: 测试框架  点击:(59)  评论:(0)  加入收藏
这个web自动化测试框架真香!在web自动化测试当中, selenium架构应该是很难绕过的,很多宣称要超 selenium的下一代web自动化测试框架最终都败下阵来。不过,selenium的api确实比较...【详细内容】
2019-12-17  Tags: 测试框架  点击:(75)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(27)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(56)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条