使用 Chai 进行质量保证和测试

使用 Chai 进行质量保证和测试

使用 Chai 进行质量保证和测试的方法如下:

1.了解 JavaScript 断言的工作原理

assert.isNull``assert.isNotNull

JavaScript 断言的工作原理是这样的:

  • 断言是一种用来检查代码是否符合预期的方法,通常用于测试和调试。
  • 断言可以使用 assert 函数或者 console.assert 方法来实现,它们接受一个条件表达式和一个可选的错误信息作为参数。
  • 如果条件表达式为真,断言通过,什么也不发生;如果条件表达式为假,断言失败,抛出一个错误或者在控制台输出错误信息。
  • 断言可以帮助我们发现代码中的逻辑错误、边界情况、非法输入等问题,提高代码的质量和可靠性。
  • 但是断言也有一些局限性,比如它不能替代正常的异常处理,它只能用于开发和测试阶段,它可能会影响代码的性能和连贯性等。
  • 因此,断言应该谨慎使用,只在必要的地方进行检查,避免过度依赖或滥用。

如果你想了解更多关于 JavaScript 断言的内容,你可以参考以下链接:

2.测试变量或函数是否已定义

assert.isDefined()``assert.isUndefined()

3.使用 Assert.isOk() 和 Assert.isNotOK()

isOk() 用来测试值是否为真值,isNotOk() 用来测试值是否为假值。

4.测试真实性

isTrue() 仅当给出的值为 Boolean 的 true 时可以通过测试;isNotTrue() 则会在给出除 true 以外的值时通过测试。

isFalse()isNotFalse() 同样存在,与上面提到的两个方法类似,只不过它们针对值为 false 的布尔值。

5.用两个等号断言相等

equal() 使用 == 比较对象。

assert.equal``assert.notEqual
assert.equal(12, '12', 'Numbers are coerced into strings with ==');
assert.notEqual({ value: 1 }, { value: 1 }, '== compares object references');

6.用三个等号断言严格相等

strictEqual() 使用 “= = =” 比较对象。

assert.strictEqual``assert.notStrictEqual
assert.strictEqual(6 * '2', 12);//由于 6 * '2' 中的 '2' 是一个字符串,因此它将被转换为数字 2。表达式 6 * '2' 的结果是 12

7.用 Assert.deepEqual() 和 Assert.notDeepEqual() 断言深度相等

deepEqual() 断言两个对象是否深度相等

assert.deepEqual``assert.notDeepEqual
在 JavaScript 中,assert.deepEqual() 方法用于比较两个对象是否相等,包括它们的属性和属性值。如果两个对象的属性和属性值相同,则返回 true;否则返回 false

8.比较两个元素的属性

assert.isAbove:n1>n2 或 assert.isAtMost:n1<=n2

9.测试一个值是否小于或等于另一个值

assert.isBelow`:n1<n2 或 `assert.isAtLeast:n1>=n2

10.测试某个值是否在特定范围内

.approximately(actual, expected, delta, [message])
assert.approximately
assert.approximately(weirdNumbers(0.5), 1, 0.5);
assert.approximately(weirdNumbers(0.2), 1, 0.8);

断言 actual 等于 expected,在 +/- delta 的范围内。

11.测试某个值是否为数组

assert.isArrayassert.isNotArray

12.测试数组是否包含项目

assert.include``assert.notInclude

13.测试某个值是否为字符串

isStringisNotString 断言一个值是否为字符串。

assert.isString``assert.isNotString

14.测试字符串是否包含子字符串

include()notInclude() 同样可以用于字符串。 include() 用于断言字符串中包含某个子字符串。

assert.include``assert.notInclude

15.使用正则表达式测试字符串

match() 断言一个值匹配一个正则表达式(第二个参数)。

assert.match``assert.notMatch

16.测试对象是否具有某个属性

property 断言一个对象含有给定属性。

assert.property``assert.notProperty

17.测试值是否为特定数据结构类型

#typeOf 断言一个值的类型符合给定的类型,这个类型与 Object.prototype.toString 一致。

assert.typeOf``assert.notTypeOf

18.测试对象是否是构造函数的实例

#instanceOf 断言一个对象是一个构造器的实例。

assert.instanceOf``assert.notInstanceOf
assert.instanceOf(airlinePlane, Object, 'everything is an Object');

19.使用 Chai-HTTP 在 API 端上运行功能测试

序号方法描述
1GET请求指定的页面信息,并返回实体主体。
2HEAD类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4PUT从客户端向服务器传送的数据取代指定的文档的内容。
5DELETE请求服务器删除指定的页面。
6CONNECTHTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7OPTIONS允许客户端查看服务器的性能。
8TRACE回显服务器收到的请求,主要用于测试或诊断。
9PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新 。

Mocha 允许你使用名为 chai-http 的插件测试异步操作,例如调用 API 端点。

以下是使用 chai-http 测试名为 'GET /hello?name=[name] => "hello [name]"' 的套件的示例:

suite('GET /hello?name=[name] => "hello [name]"', function () {
  test('?name=John', function (done) {
    chai
      .request(server)
      .keepOpen()
      .get('/hello?name=John')
      .end(function (err, res) {
        assert.equal(res.status, 200, 'Response status should be 200');
        assert.equal(res.text, 'hello John', 'Response should be "hello John"');
        done();
      });
  });
});

该测试向服务器发送一个 GET 请求,并将名称作为 URL 查询字符串(?name=John)。 在end 方法的回调函数中,接收到响应对象(res)并包含 status 属性。

第一个 assert.equal 检查状态是否为 200。 第二个 assert.equal 检查响应字符串(res.text)是否为 "hello John"

同时,请注意测试的回调函数中的 done 参数。 在测试结束时,调用它且不带参数,是发出异步操作完成所必需的信号。

异步操作:是一种编程模型,它允许程序在等待某个操作完成时继续执行其他任务。在 JavaScript 中,异步操作通常使用回调函数来实现。在传统的同步编程模型中,程序的执行是按照代码顺序依次执行的。而在异步编程模型中,程序的执行顺序不再与代码顺序一致,因为异步操作的结果不是立即返回的。相反,程序会继续执行其他任务,直到异步操作完成并调用回调函数。这种编程模型可以提高程序的性能和响应速度,因为它允许程序在等待某个操作完成时继续执行其他任务。如果你想了解更多关于 JavaScript 异步编程的内容,可以参考这个 菜鸟教程

最后,请注意 request 方法后面的 keepOpen 方法。 通常,你会从命令行中运行你的测试,或者作为自动集成过程的一部分,你可以让 chai-http 自动启动和停止你的服务器。

然而,当你提交项目链接时运行的测试需要你的服务器是正常的,所以你需要使用 keepOpen 方法来防止 chai-http 停止你的服务器。

tests/2_functional-tests.js 中,修改 'Test GET /hello with no name' 测试(// #1),对响应的 statustext 使用断言来通过测试。 不要改变传递给断言的参数。

不应该有任何 URL 查询。 如果没有名称 URL 查询,端点将使用 hello Guest 进行响应。

20.使用 Chai-HTTP II 在 API 端上运行功能测试

tests/2_functional-tests.js 中,修改 'Test GET /hello with your name' 测试(// #2),对响应的 statustext 使用断言来通过测试。

通过将 ?name=<your_name> 附加到路由,将你的姓名作为 URL 查询发送。 端点响应 'hello <your_name>'

21.使用 Chai-HTTP III 的 PUT 方法对 API 请求运行功能测试

当你测试一个 PUT 请求时,你经常会随同它一起发送数据。 你在 PUT 请求中包含的数据被称为请求的主体。

要将 PUT 请求和 JSON 对象发送到 '/travellers' 端点,你可以使用 chai-http 插件的 putsend 方法:

 chai
  .request(server)
  .keepOpen()
  .put('/travellers')
  .send({
    "surname": [last name of a traveller of the past]
  })
  ...

并且路由响应如下:

{
  "name": [first name],
  "surname": [last name],
  "dates": [birth - death years]
}

请参阅服务器代码以了解对 '/travellers' 端点的不同响应。


tests/2_functional-tests.js 中,更改 'Send {surname: "Colombo"}' 测试(// #3),并使用 putsend 方法来测试 '/travellers' 端点。

在你的 PUT 请求中发送以下 JSON 对象。

{
  "surname": "Colombo"
}

request.end 的返回中检查以下情况:

  1. status 应该是 200
  2. type 应该是 application/json
  3. body.name 应该是 Cristoforo
  4. body.surname 应该是 Colombo

请按照以上顺序书写断言,顺序错误会影响系统判定。 此外,请确保在完成后删除 assert.fail()

assert.equal(res.status, 200);
assert.equal(res.type, 'application/json');
assert.equal(res.body.name, 'Cristoforo');
assert.equal(res.body.surname, 'Colombo');

22.使用 Chai-HTTP IV 的 PUT 方法对 API 响应运行功能测试

这个练习与上一个类似。

现在你知道如何测试一个 PUT 请求了,轮到你从头开始做了。


tests/2_functional-tests.js 中,更改 'Send {surname: "da Verrazzano"}' 测试(// #4)并使用 putsend 方法来测试 '/travellers' 端点。

test('Send {surname: "da Verrazzano"}', function(done) {
      chai
        .request(server)
        .keepOpen()
        .put('/travellers')
        .send({
          "surname": "da Verrazzano"
        })
        .end(function(err,res){
          assert.equal(res.status,200);
          assert.equal(res.type,'application/json');
          assert.equal(res.body.name,'Giovanni');
          assert.equal(res.body.surname,'da Verrazzano');
          done();
        })
});

23.使用无头浏览器模拟操作

在接下来的挑战中,你将使用无头浏览器模拟人类与页面的交互。

无头浏览器是没有 GUI 的 Web 浏览器。 它们能够以与常规浏览器相同的方式呈现和解释 HTML、CSS 和 JavaScript,这使得它们对于测试网页特别有用。

在下面的挑战中,你将使用Zombie.js,它是一个轻量级的无头浏览器,不依赖额外的二进制文件来安装。 这一特点使其可以在 Replit 这样的有限环境中使用。 但是还有许多其他更强大的无头浏览器选项。

Mocha 允许你在任何实际测试运行之前运行一些代码。 这对做一些事情很有用,比如向数据库添加条目,这些条目将在其余测试中使用。

使用无头浏览器,在运行测试之前,你需要 访问 你要测试的页面。

suiteSetup 钩子仅在测试套件开始时执行一次。

还有其他几种钩子类型,可以在每次测试前、每次测试后或测试套件结束时执行代码。 有关更多信息,请参阅 Mocha 文档。


tests/2_functional-tests.js 中,紧跟在 Browser 声明之后,将你的项目 URL 添加到变量的 site 属性:

Browser.site = 'https://boilerplate-mochachai.your-username.repl.co'; // Your URL here

然后在 'Functional Tests with Zombie.js' 套件的根级别,使用以下代码实例化 Browser 对象的新实例:

const browser = new Browser();

并使用 suiteSetup 钩子将 browser 定向到带有以下代码的 / 路由:

suiteSetup(function(done) {
  return browser.visit('/', done);
});

24.使用无头浏览器运行功能测试

在页面上有一个输入表单。 它将数据作为 AJAX 请求发送到 PUT /travellers 端点。

当请求成功完成后,客户端代码将一个包含响应信息的 <div> 附加到 DOM 中。

下面是一个如何使用 Zombie.js 与表单互动的例子。

test('Submit the surname "Polo" in the HTML form', function (done) {
  browser.fill('surname', 'Polo').then(() => {
    browser.pressButton('submit', () => {
      browser.assert.success();
      browser.assert.text('span#name', 'Marco');
      browser.assert.text('span#surname', 'Polo');
      browser.assert.elements('span#dates', 1);
      done();
    });
  });
});

首先, browser 对象的 fill 方法在表格的 surname 字段中填入值 'Polo'fill 返回一个 promise,所以 then 被链接起来。

then 回调中,browser 对象的 pressButton 方法用于调用表单的 submit 的事件侦听器。 pressButton 方法是异步的。

然后,一旦收到来自 AJAX 请求的响应,就会做出一些断言来确认:

  1. 响应状态是 200
  2. <span id='name'></span> 元素的文本是 'Marco'
  3. <span id='surname'></span> 元素的文本是 'Polo'
  4. 1<span id='dates'></span> 元素。

最后,执行 done,这是异步测试所必需的。


tests/2_functional-tests.js 中,在 'Submit the surname "Colombo" in the HTML form' 测试(// #5),自动执行以下操作:

  1. 在表格中填写姓氏 Colombo
  2. 点击提交按钮

pressButton 回调中:

  1. 断言状态是正常的 200
  2. 断言元素 span#name 中的文本是 'Cristoforo'
  3. 断言元素 span#surname 中的文本是 'Colombo'
  4. 断言有 span#dates 元素,它们的计数是 1

不要忘记删除 assert.fail() 调用。

test('Submit the surname "Colombo" in the HTML form', function(done) {
      browser.fill('surname', 'Colombo').then(() => {
        browser.pressButton('submit', () => {
          browser.assert.success();
          browser.assert.text('span#name', 'Cristoforo');
          browser.assert.text('span#surname', 'Colombo');
          browser.assert.elements('span#dates', 1);
          done();
   });
  });
});

25.使用 无头浏览器 II 运行功能测试

tests/2_functional-tests.js 中,在 'Submit the surname "Vespucci" in the HTML form' 测试(// #6),自动执行以下操作:

  1. 在表格中填写姓氏 Vespucci
  2. 点击提交按钮

pressButton 回调中:

  1. 断言状态是正常的 200
  2. 断言元素 span#name 中的文本是 'Amerigo'
  3. 断言元素 span#surname 元素中的文本是 'Vespucci'
  4. 断言有 span#dates 元素,它们的计数是 1

不要忘记删除 assert.fail() 调用。

test('Submit the surname "Vespucci" in the HTML form', function(done) {
      browser.fill('surname', 'Vespucci').then(() => {
        browser.pressButton('submit', () => {
          browser.assert.success();
          browser.assert.text('span#name', 'Amerigo');
          browser.assert.text('span#surname', 'Vespucci');
          browser.assert.elements('span#dates', 1);
          done();
        });
      });
    });
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值