前端架构: 脚手架通用框架封装之添加测试框架(教程六)

添加测试框架

  • 接上文,仍旧在 abc-cli 项目中

  • 参考:https://blog.csdn.net/Tyro_java/article/details/136438882

  • 现在要在脚手架项目中安装测试工具,选择 jest

  • 文档:https://www.npmjs.com/package/jest

  • 数据:Weekly Downloads 19,759,155 (动态)

  • 可见是一个比较流行的测试库,现在安装它

  • $ npm i jest execa -D -w packages/cli

  • 注意,这里的 -D 它是开发依赖,用于测试

  • 之后,在 abc-cli/packages/cli/package.json 中的 scripts 进行修改

    js 复制代码
    {
      "scripts": {
        "test": "jest"
      }
    }
  • 在 abc-cli/packages/cli/tests/cli.test.js 中编写

    js 复制代码
    test('run error command', () => {
      expect(1 + 1).toBe(2);
    })
  • 进入 abc-cli/packages/cli 目录下,执行 $ npm run test, 查看输出

    shell 复制代码
    $ npm run test
    
    > @abc.com/cli@0.0.0 test
    > jest
    
    PASS  __tests__/cli.test.js
      ✓ run error command (2 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        0.329 s
    Ran all test suites.
  • 好,看起来一切正常,现在我们来测试CLI内部的一些API

    js 复制代码
    import path from 'node:path';
    import { execa } from 'execa';
    
    const CLI = path.join(__dirname, '../bin/cli.js');
    const bin = () => () => execa(CLI);
    
    test('run error command', () => {
      expect(1 + 1).toBe(2);
    })
    
    test('run cli', async () => {
      const ret = await bin()();
      console.log(ret);
    })
  • 这里拿到 cli 中的api,进行执行测试,但是发现报错了

    shell 复制代码
    Details:
    
        /Users/xx/abc-cli/packages/cli/__tests__/cli.test.js:1
        ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import path from 'node:path';
                                                                                          ^^^^^^
    
        SyntaxError: Cannot use import statement outside a module
    
          at Runtime.createScriptFromCode (../../node_modules/jest-runtime/build/index.js:1505:14)
  • 可以看到,它这里把整个代码当做 commonjs 来运行, jest本身提供的就是 commonjs 的方式,这里涉及到了如何让 jest 支持 esm

  • jest 默认集成了 babel, 我们利用这个特性,创建 babel 的配置文件,新建 abc-cli/packages/cli/babel.config.cjs

  • 安装 babel, 在 abc-cli 目录中,$ npm i @babel/core @babel/preset-env -D -w packages/cli

  • 编辑 babel.config.cjs, 注意,这里是 cjs 代表在ESM中使用commonjs规则

    js 复制代码
    module.exports = {
      presets: [
        ['@babel/preset-env']
      ]
    }
  • 之后,在同级目录添加 jest.config.cjs

    js 复制代码
    module.exports = {
      transformIgnorePatterns: []
    }
  • 再次在 abc-cli/packages/cli 目录下,执行 $ npm run test, 查看输出

  • 虽然看似报错,但是是这个命令的执行结果

    shell 复制代码
    > @abc.com/cli@0.0.0 test
    > jest
    
    FAIL  __tests__/cli.test.js
      ✓ run error command (2 ms)
      ✕ run cli (165 ms)
    
      ● run cli
    
        Command failed with exit code 1: /Users/Wang/Desktop/DD/abc-cli/packages/cli/bin/cli.js
        abc.com success log test version 0.0.0
        Usage: abc-cli <command> [options]
    
        Options:
          -V, --version          output the version number
          -d, --debug            是否开启调试模式 (default: false)
          -h, --help             display help for command
    
        Commands:
          init [options] [name]  init project
          help [command]         display help for command
    
          at makeError (node_modules/execa/lib/error.js:60:11)
          at _callee$ (node_modules/execa/index.js:124:35)
          at call (node_modules/execa/index.js:2:1)
          at Generator.tryCatch (node_modules/execa/index.js:2:1)
          at Generator._invoke [as next] (node_modules/execa/index.js:2:1)
          at asyncGeneratorStep (node_modules/execa/index.js:2:1)
          at asyncGeneratorStep (node_modules/execa/index.js:2:1)
    
    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 passed, 2 total
    Snapshots:   0 total
    Time:        0.792 s, estimated 2 s
    Ran all test suites.
  • 现在就可以继续完善了,修改 abc-cli/packages/cli/tests/cli.test.js

    js 复制代码
    import path from 'node:path';
    import { execa } from 'execa';
    
    const CLI = path.join(__dirname, '../bin/cli.js');
    const bin = () => (...args) => execa(CLI, args);
    
    test('run error command', () => {
      expect(1 + 1).toBe(2);
    })
    
    test('run cli', async () => {
      const ret = await bin()(iii);
      console.log(ret);
    })
  • 执行 $ npm run test, 查看输出

    shell 复制代码
    > @abc.com/cli@0.0.0 test
    > jest
    
      console.log
        {
          command: '/Users/Wang/Desktop/DD/abc-cli/packages/cli/bin/cli.js iii',
          escapedCommand: '"/Users/Wang/Desktop/DD/abc-cli/packages/cli/bin/cli.js" iii',
          exitCode: 0,
          stdout: '',
          stderr: 'abc.com success log test version 0.0.0\nabc.com ERR! 未知的命令:iii ',
          all: undefined,
          failed: false,
          timedOut: false,
          isCanceled: false,
          killed: false
        }
    
          at log (__tests__/cli.test.js:13:10)
    
    PASS  __tests__/cli.test.js
      ✓ run error command (2 ms)
      ✓ run cli (141 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        0.744 s, estimated 1 s
    Ran all test suites.
  • 这样,看到用例都通过了,但是这是一个没有注册的命令

  • 继续优化, 编写 abc-cli/packages/cli/tests/cli.test.js 如下

    js 复制代码
    import path from 'node:path';
    import { execa } from 'execa';
    
    const CLI = path.join(__dirname, '../bin/cli.js');
    const bin = () => (...args) => execa(CLI, args);
    
    // 正常测试
    test('run normal test', () => {
      expect(1 + 1).toBe(2);
    })
    
    // 测试 cli 未注册命令
    test('run cli', async () => {
      const { stderr } = await bin()('iii');
      expect(stderr).toContain('未知的命令:iii')
    })
    
    // 测试 --help
    test('test --help', async () => {
      let error = null;
      try {
        await bin()('--help');
      } catch(e) {
        error = e;
      }
      expect(error).toBe(null);
    })
    
    // 测试 -V
    test('test --version', async () => {
      const { stderr } = await bin()('-V');
      expect(stderr).toContain(require('../package.json').version)
    })
    
    // 测试是否开启 debug 模式
    test('test --debug', async () => {
      let error = null;
      try {
        await bin()('-d');
      } catch(e) {
        error = e;
      }
      expect(error.message).toContain('launch debug mode');
    })
  • 运行 $ npm run test 查看输出结果

    shell 复制代码
    > @abc.com/cli@0.0.0 test
    > jest
    
    PASS  __tests__/cli.test.js
      ✓ run normal test (2 ms)
      ✓ run cli (148 ms)
      ✓ test --help (140 ms)
      ✓ test --version (131 ms)
      ✓ test --debug (142 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       5 passed, 5 total
    Snapshots:   0 total
    Time:        1.218 s
    Ran all test suites
  • 通过以上,我们把整个测试框架和一些基础用例编写完成,在实际场景中可以继续挖掘出更多用法

  • 相关代码参考:v_test

相关推荐
Watermelo6178 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_7482489410 分钟前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_7482356121 分钟前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O2 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink5 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-7 小时前
验证码机制
前端·后端
燃先生._.8 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖9 小时前
[react]searchParams转普通对象
开发语言·前端·javascript