使用匹配器

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

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

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

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

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 = + ;
expect(value).toBeGreaterThan();
expect(value).toBeGreaterThanOrEqual(3.5);
expect(value).toBeLessThan();
expect(value).toBeLessThanOrEqual(4.5); // toBe and toEqual are equivalent for numbers
expect(value).toBe();
expect(value).toEqual();
});
test('两个浮点数字相加', () => {
const value = 0.1 + 0.2;
//expect(value).toBe(0.3); 这句会报错,因为浮点数有舍入误差
expect(value).toBeCloseTo(0.3); // 这句可以运行
});

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

字符串

使用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')
},);
} 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')
},);
} test('the data is peanut butter', (done) => {
function callback(data) {
expect(data).toBe('peanut butter');
done()
}
fetchData(callback);
});

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

Promise

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

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

test('the data is peanut butter', () => {
expect.assertions();
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();
return fetchData().catch(e => expect(e).toMatch('error'));
});

.resolves/.rejects

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

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

Async/Await

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

test('the data is peanut butter', async () => {
expect.assertions();
const data = await fetchData();
expect(data).toBe('peanut butter');
}); test('the fetch fails with an error', async () => {
expect.assertions();
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

以上内容就是本篇的全部内容以上内容希望对你有帮助,有被帮助到的朋友欢迎点赞,评论。
如果对软件测试、接口测试、自动化测试、面试经验交流。感兴趣可以关注我,我们会有同行一起技术交流哦。

前端测试框架Jest——语法篇的更多相关文章

  1. 前端测试框架Jest系列教程 -- 简介

    写在前面: 随着互联网日新月异的发展,用户对于页面的美观度,流畅度以及各方面的体验有了更高的要求,我们的网页不再是简单的承载文字,图片等简单的信息传递给用户,我们需要的是更加美观的页面展示,更快的浏览 ...

  2. 前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)

    写在前面: 在JavaScript代码中,异步运行是很常见的.当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试.Jest提供了几种方法来处理这个问题. 测试异步 ...

  3. 前端测试框架Jest系列教程 -- Mock Functions

    写在前面: 在写单元测试的时候有一个最重要的步骤就是Mock,我们通常会根据接口来Mock接口的实现,比如你要测试某个class中的某个方法,而这个方法又依赖了外部的一些接口的实现,从单元测试的角度来 ...

  4. 前端测试框架Jest系列教程 -- Global Functions(全局函数)

    写在前面: Jest中定义了很多全局性的Function供我们使用,我们不必再去引用别的包来去实现类似的功能,下面将列举Jest中实现的全局函数. Jest Global Functions afte ...

  5. 前端测试框架Jest系列教程 -- Mock Functions(模拟器)

    写在前面: 在写单元测试的时候有一个最重要的步骤就是Mock,我们通常会根据接口来Mock接口的实现,比如你要测试某个class中的某个方法,而这个方法又依赖了外部的一些接口的实现,从单元测试的角度来 ...

  6. 前端测试框架jest 简介

    转自: https://www.cnblogs.com/Wolfmanlq/p/8012847.html 作者:Ken Wang 出处:http://www.cnblogs.com/Wolfmanlq ...

  7. 前端测试框架Jest系列教程 -- Matchers(匹配器)

    写在前面: 匹配器(Matchers)是Jest中非常重要的一个概念,它可以提供很多种方式来让你去验证你所测试的返回值,本文重点介绍几种常用的Matcher,其他的可以通过官网api文档查看. 常用的 ...

  8. 前端测试框架Jest系列教程 -- Expect(验证)

    写在前面 在编写测试时,我们通常需要检查值是否满足某些条件,Jest中提供的expect允许你访问很多“Matchers”,这些“匹配器”允许您验证不同的东西. Expect 可以验证什么 Jest中 ...

  9. 前端测试框架 Jest

    前端测试工具一览 前端测试工具也和前端的框架一样纷繁复杂,其中常见的测试工具,大致可分为测试框架.断言库.测试覆盖率工具等几类.在正式开始本文之前,我们先来大致了解下它们: 测试框架 测试框架的作用是 ...

随机推荐

  1. PHP popen() 函数

    定义和用法 popen() 函数使用 command 参数打开进程文件指针. 如果出错,该函数返回 FALSE. 语法 popen(command,mode) 参数 描述 command 必需.规定要 ...

  2. PHP mkdir() 函数

    定义和用法 mkdir() 函数创建目录. 如果成功该函数返回 TRUE,如果失败则返回 FALSE. 语法 mkdir(path,mode,recursive,context) 参数 描述 path ...

  3. log4net用法实例

    内容转载自:https://www.cnblogs.com/youring2/archive/2011/04/27/2030424.html 1.引用log4net.dll 2.在AssemblyIn ...

  4. json&pickle&shelve

    之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了 ...

  5. 使用cors完成跨域请求处理

    跨域的含义 同源策略以及其限制内容 同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS.CSFR等攻击.所谓同源是指"协议+域名+端口&quo ...

  6. CSS 学习第一天

    css的三种引入方式: 1.内嵌:直接在标签中添加style属性 格式:<标签名 style="样式1:样式值1:样式2:样式值2"> 2.内联:在head标签中添加& ...

  7. java流程控制语句if

    一 if语句 if语句是指如果满足某种条件,就进行某种处理. 格式: if (条件语句){ 执行语句; …… } 流程图: 例如: public class IfDemo01 { public sta ...

  8. java BigInteger与BigDecimal

    一 BigInteger java中long型为最大整数类型,对于超过long型的数据如何去表示呢.在Java的世界中,超过long型 的整数已经不能被称为整数了,它们被封装成BigInteger对象 ...

  9. C#LeetCode刷题之#101-对称二叉树(Symmetric Tree)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4068 访问. 给定一个二叉树,检查它是否是镜像对称的. 例如,二 ...

  10. .NetCore(Avalonia) 项目dll混淆,Ubuntu 或者deepin操作系统 deb安装包解压,重新打包

    .NetCore(Avalonia) 项目dll混淆,deb安装包解压,重新打包 本文分为两部分,一部分是介绍使用 DotNetReactor6.0 及以上版本混淆.netcore项目的dll. 另一 ...