51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1038|回复: 0
打印 上一主题 下一主题

[资料] 浅谈单元测试mocha、chai和supertest

[复制链接]
  • TA的每日心情
    无聊
    3 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2023-5-19 10:55:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    mocha单元测试
      1. 因为有时候在代码中加了新的东西需要反复测试接口或者别人要求重新跑接口非常的繁琐。
      2. 所有我们需要一个帮我们重复测试的东西那就是mocha。
      3. 先下载 一定不要全局安装 不然后期如果这个模块更新有问题影响的是全部的文件。
      npm i mocha

      4. 因为不是全局安装 没办法通过命令直接获取我们还得去根目录下找bin文件太繁琐了所以我们需要配置 pakeage.json文件里的内容改脚本内的 test 起其他名字也行  。
      { ---------------------------- 初始化内容
        "name": "mocah",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": { // ---------改这里
          "test": "mocha"
        },--------------------------end
        "author": "",
        "license": "ISC",
        "dependencies": { ----------这个是后面案例需要的 包
          "chai": "^4.3.6",
          "koa": "^2.13.4",
          "mocha": "^10.0.0",
          "supertest": "^6.2.4"
        }
      }


      5. 如果执行的话直接 npm  test    如果你不是 test最好加上    npm run  名字 这个会直接找你文件夹下的 test文件  这个和上面的  npm test 没有关联!!!  mocha这个模块会找 名字带有test 文件的名字。
      6.封装一个方法方便演示
      function maxNum(...arr) {
        return arr.length ? Math.max(...arr) : 0; //就是取传来的最大值 没有传值就返回0
      }
      module.exports = maxNum; //导出


      7. 编写测试 用的是node 自带的配合mocha 它还提供了describe 和it 方法非常的好用 具体看代码:
      const maxNum = require("../maxNum");
      const assert = require("assert");
      describe("第一组测试", () => {
        describe("小测试1", () => {
          it("sum() 结果 0 ", () => {
            // 这个是node 内置的 assert测试 strictEqual表示严格模式下
            assert.strictEqual(maxNum(), 0);//断言 在严格模式下maxNum()结果是0
          });
        });
        describe("小的测试2", () => {
          it("sum(1) 结果 1", () => {
            // 这个是node 内置的 assert测试 strictEqual表示严格模式下
            assert.strictEqual(maxNum(1), 2); // 专门写错一个
          });
        });
      });
      // 第二组大的测试
      describe("第二组大的测试", () => {
        it("sum(1,2) 结果 2 ", () => {
          // 这个是node 内置的 assert测试 strictEqual表示严格模式下
          assert.strictEqual(maxNum(1, 2), 2); //断言在严格模式下 maxNum(1,2)值是2
        });
        it("sum(1,2,3) 结果 3", () => {
          // 这个是node 内置的 assert测试 strictEqual表示严格模式下
          assert.strictEqual(maxNum(1, 2, 3), 3);//断言在严格模式下 maxNum(1,2,3)值是3
        });
      });
      -------------------------------------结果---------------------
       第一组测试
          小测试1
            ? sum() 结果 0
          小的测试2
            1) sum(1) 结果 1
        第二组大的测试
          ? sum(1,2) 结果 2
          ? sum(1,2,3) 结果 3
        3 passing (21ms)
        1 failing
        1) 第一组测试
             小的测试2
               sum(1) 结果 1:
            AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
      1 !== 2
            + expected - actual
            -1
            +2
            at Context.<anonymous> (test\test.js:14:14)
            at processImmediate (node:internal/timers:466:21)


      chai 可以更加方便也比node 自带的功能 要更加强大
      官网 :https://www.chaijs.com/
      1. 它还整合了需要其他模块的风格 比如 expect 风格 assert风格 should 风格等多种风格
      2. 下载安装 chai
      npm install  chai

      3. assert 风格
      const maxNum = require("../maxNum"); //导入上面那个函数
      const chai = require("chai"); //导入下载好的模块
      const assert = chai.assert;// 用这个模块中的assert方法
      describe("测试", () => {
        it("使用 assert 风格", () => {
          assert.equal(maxNum(1, 5, 2), 5);// 表示断言maxNum(1,5,2)结果是 5
          assert.typeOf(maxNum(1, 5, 2), "Number");// 断言maxNum(1,5,2)结果应该是个Number
        });
      });
      --------------------------log--------------
        测试
          ? 使用 assert 风格
        1 passing (12ms)


      4.should风格 这种链式调用的风格的。
      const maxNum = require("../app");
      const chai = require("chai");
      chai.should(); // 调用一下
      describe("测试", () => {
        it("使用 should 风格", () => {
          //这个函数应该存在并且值等于1 并且值是 Number类型
          maxNum(1).should.exist.and.equal(1).and.be.a("Number");
          // 分开写也行
          maxNum(1).should.equal(1); // 值是1
          maxNum(1).should.exist; // 应该存在
          maxNum(1).should.be.a("Number"); // 应该是Number类型
        });
      });
      -----------------------log---------------------------------
       测试
           使用 should 风格
        1 passing (11ms)


      5.expect 风格的 这种期望风格的
      const maxNum = require("../app");
      const chai = require("chai");
      const expect = chai.expect;
      describe("测试", () => {
        it("使用 expect 风格", () => {
          // 期望这个值是 存在的
          expect(maxNum(1)).to.exist;
          //期望它是个Number类型
          expect(maxNum(1)).to.be.a("Number");
          // 期望它的值是1
          expect(maxNum(1)).to.equal(1);
        });
      });
      -----------------------------------------log -----------------
           使用 expect 风格
        1 passing (12ms)


      异步测试
      1.  在好多情况下 比如接口 去操作数据库  去读取文件都是异步在上面那些异步就不好用了。
      2. 可以使用回调函数  不管演示的 是promise 用async await 方法实现异步测试。
      3. 异步读取文件。
      const chai = require("chai");
      // 引入fs 模块 把他改装为promises对象来处理异步 或者你可以写成回调函数
      const fs = require("fs").promises;
      const assert = chai.assert;
      // 异步读取文件
      describe("测试异步", () => {
        it("读取文件", async () => {
          // 异步读取文件 等待文件读取成功才能进行抛出判断
          let data = await fs.readFile("./my.text");
          assert.equal(data, "111");//断言这个文件中的数据是111
        });
      });
      ----------------------------------------log
       测试异步
            读取文件
        1 passing (14ms)


      4.异步测试接口 这里我们用到是 supertest 这个小模块
      4.1 下载安装supertest
      npm  install supertest

      4.2 这个模块可以发送网络请求还有集成的断言  非常的好用
      const koa = require("koa"); //引入koa模块
      const app = new koa();
      // 发get 请求就发送 json {ok:1}
      app.use((ctx, next) => {
        ctx.body = { ok: 1 };
      });
      // 把ap导出去
      module.exports = app;
      -----------------------------------上面是创建服务器模块 不在同一个文件夹------------
      const supertest = require("supertest"); // 导入模块
      const app = require("../app"); //引入app
      describe("接口测试", () => {
        let server;
        it("测试get接口", async () => {
          await supertest(server) // 用async  await 等待测试结果
            .get("/")//发起get 请求
            .expect(200, { ok: 1 }); // 进行判断看是ok:1吗
        });
        // 钩子函数在所有测试跑之前执行
        before(() => {
          // 开启服务器
          server = app.listen(3000);
        });
        // 钩子函数在所有测试跑完之后执行
        after(() => {
          // 关闭服务器
          server.close();
        });
      });


      钩子函数
      1. 在一个大 的describe作用域中 before是所有测试之前 after 是所有请求之后。
      2. beforeEach是 每一个小的测试之前 afterEach是每一个小的测试之后。
      3. 这个就可以很方便的 比如 开启数据库 打开服务器等等 在不同的地方干不同的事件。
        after(() => {
          // 关闭服务器
          server.close();
        });
      });
      钩子函数
      const assert = require("chai").assert;
      const str = "test";
      describe("测试钩子函数1", () => {
        it("测试它的数据类型是不是 string", () => {
          assert.typeOf(str, "string");
        });
        it("测试它值是不是  test", () => {
          assert.equal(str, "test");
        });
        // 定义钩子函数
        beforeEach(() => {
          console.log("我是每一个函数1测试之前的");
        });
        afterEach(() => {
          console.log("我是每一个函数1测试之后的");
        });
        // 全部测试之前和之后
        before(() => {
          console.log("我是函数1之前的");
        });
        after(() => {
          console.log("我是函数1之后的 ");
        });
      });
      describe("测试钩子函数2", () => {
        it("测试它的数据类型是不是 存在呀", () => {
          assert.exists(str);
        });
        it("断言它值不是  数字 ", () => {
          assert.isNotNumber(str);
        });
        // 定义钩子函数
        beforeEach(() => {
          console.log("我是每一个函数2测试之前的");
        });
        afterEach(() => {
          console.log("我是每一个函数2测试之后的");
        });
        // 全部测试之前和之后
        before(() => {
          console.log("我是函数2之前的");
        });
        after(() => {
          console.log("我是函数2之后的 ");
        });
      });
      -------------------------------log------------------
      测试钩子函数1
      我是函数1之前的
      我是每一个函数1测试之前的
      · 测试它的数据类型是不是 string
      我是每一个函数1测试之后的
      · 测试它值是不是 test
      我是函数1之后的
      测试钩子函数2
      我是函数2之前的
      我是每一个函数2测试之前的
      · 测试它的数据类型是不是 存在呀
      我是每一个函数2测试之后的
      我是每一个函数2测试之前的
      · 断言它值不是 数字
      我是每一个函数2测试之后的
      我是函数2之后的
      4 passing (37ms)



    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 14:58 , Processed in 0.063072 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表