IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 关于 nodejs 覆盖率的探索 -> 正文阅读

[开发测试]关于 nodejs 覆盖率的探索

这个研究起源于这个帖子 如何收集 nodejs 服务端的测试覆盖率(Nodejs), 由于自己之前对这块其实是没有研究过的,所以特地花了些时间去了解了下。

知识储备

虽然说没有做过这块的覆盖率研究,但是对于针对nodejs这块的覆盖率工具之前是有做过一定的了解的,主要是在 nyc 以及 istanbul-middleware (以下简称IM)。

关于两者的一些说明可以去看下这两篇文章,里面讲了挺多内容的 探索istanbul/nyc代码覆盖工具的原理 React Native 代码覆盖率获取探索 (二)

nyc的初步尝试

由于nodejs这块很少会用到babel编译这种方式,所以我们就放弃了之前 聊聊前端代码覆盖率 (长文慎入) 介绍到的 babel-plugin-istanbul。 而是直接采用nyc运行前插桩的方式。

这里可以直接查看下这个栗子 nyc-expresss-coverage-demo

其实就是通过 nyc instrument的命令 对相应的代码目录进行插桩操作。 相应的插桩后的文件如:

data.js

module.exports = {
    authors: [
        {
            id: '1',
            name: 'John Irving',
            country: 'USA',
            dob: '03/02/1942'
        },
        {
            id: '2',
            name: 'Gabriel Garcia Marquez',
            country: 'Colombia',
            dob: '03/06/1927'
        },
        {
            id: '3',
            name: 'Salman Rushdie',
            country: 'India',
            dob: '06/19/1947'
        },
        {
            id: '4',
            name: 'Stanislaw Lem',
            country: 'Poland',
            dob: '09/12/1921',
            deceased: true
        }
    ]
};

变为了

function cov_106hx7e2f0() {
  var path = "/Users/sai/projects/nyc-expresss-coverage-demo/server/data.js";
  var hash = "ff103e96a45dea0c0d53a6e72b3c27f5cdf62f87";
  var global = new Function("return this")();
  var gcv = "__coverage__";
  var coverageData = {
    path: "/Users/sai/projects/nyc-expresss-coverage-demo/server/data.js",
    statementMap: {
      "0": {
        start: {
          line: 1,
          column: 0
        },
        end: {
          line: 29,
          column: 2
        }
      }
    },
    fnMap: {},
    branchMap: {},
    s: {
      "0": 0
    },
    f: {},
    b: {},
    _coverageSchema: "1a1c01bbd47fc00a2c39e90264f33305004495a9",
    hash: "ff103e96a45dea0c0d53a6e72b3c27f5cdf62f87"
  };
  var coverage = global[gcv] || (global[gcv] = {});

  if (!coverage[path] || coverage[path].hash !== hash) {
    coverage[path] = coverageData;
  }

  var actualCoverage = coverage[path];
  {
    // @ts-ignore
    cov_106hx7e2f0 = function () {
      return actualCoverage;
    };
  }
  return actualCoverage;
}

cov_106hx7e2f0();
cov_106hx7e2f0().s[0]++;
module.exports = {
  authors: [{
    id: '1',
    name: 'John Irving',
    country: 'USA',
    dob: '03/02/1942'
  }, {
    id: '2',
    name: 'Gabriel Garcia Marquez',
    country: 'Colombia',
    dob: '03/06/1927'
  }, {
    id: '3',
    name: 'Salman Rushdie',
    country: 'India',
    dob: '06/19/1947'
  }, {
    id: '4',
    name: 'Stanislaw Lem',
    country: 'Poland',
    dob: '09/12/1921',
    deceased: true
  }]
};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImRhdGEuanMiXSwibmFtZXMiOlsibW9kdWxlIiwiZXhwb3J0cyIsImF1dGhvcnMiLCJpZCIsIm5hbWUiLCJjb3VudHJ5IiwiZG9iIiwiZGVjZWFzZWQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFlWTs7Ozs7Ozs7OztBQWZaQSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDYkMsRUFBQUEsT0FBTyxFQUFFLENBQ0w7QUFDSUMsSUFBQUEsRUFBRSxFQUFFLEdBRFI7QUFFSUMsSUFBQUEsSUFBSSxFQUFFLGFBRlY7QUFHSUMsSUFBQUEsT0FBTyxFQUFFLEtBSGI7QUFJSUMsSUFBQUEsR0FBRyxFQUFFO0FBSlQsR0FESyxFQU9MO0FBQ0lILElBQUFBLEVBQUUsRUFBRSxHQURSO0FBRUlDLElBQUFBLElBQUksRUFBRSx3QkFGVjtBQUdJQyxJQUFBQSxPQUFPLEVBQUUsVUFIYjtBQUlJQyxJQUFBQSxHQUFHLEVBQUU7QUFKVCxHQVBLLEVBYUw7QUFDSUgsSUFBQUEsRUFBRSxFQUFFLEdBRFI7QUFFSUMsSUFBQUEsSUFBSSxFQUFFLGdCQUZWO0FBR0lDLElBQUFBLE9BQU8sRUFBRSxPQUhiO0FBSUlDLElBQUFBLEdBQUcsRUFBRTtBQUpULEdBYkssRUFtQkw7QUFDSUgsSUFBQUEsRUFBRSxFQUFFLEdBRFI7QUFFSUMsSUFBQUEsSUFBSSxFQUFFLGVBRlY7QUFHSUMsSUFBQUEsT0FBTyxFQUFFLFFBSGI7QUFJSUMsSUFBQUEsR0FBRyxFQUFFLFlBSlQ7QUFLSUMsSUFBQUEsUUFBUSxFQUFFO0FBTGQsR0FuQks7QUFESSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0ge1xuICAgIGF1dGhvcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIG5hbWU6ICdKb2huIElydmluZycsXG4gICAgICAgICAgICBjb3VudHJ5OiAnVVNBJyxcbiAgICAgICAgICAgIGRvYjogJzAzLzAyLzE5NDInXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgICBuYW1lOiAnR2FicmllbCBHYXJjaWEgTWFycXVleicsXG4gICAgICAgICAgICBjb3VudHJ5OiAnQ29sb21iaWEnLFxuICAgICAgICAgICAgZG9iOiAnMDMvMDYvMTkyNydcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICAgIG5hbWU6ICdTYWxtYW4gUnVzaGRpZScsXG4gICAgICAgICAgICBjb3VudHJ5OiAnSW5kaWEnLFxuICAgICAgICAgICAgZG9iOiAnMDYvMTkvMTk0NydcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc0JyxcbiAgICAgICAgICAgIG5hbWU6ICdTdGFuaXNsYXcgTGVtJyxcbiAgICAgICAgICAgIGNvdW50cnk6ICdQb2xhbmQnLFxuICAgICAgICAgICAgZG9iOiAnMDkvMTIvMTkyMScsXG4gICAgICAgICAgICBkZWNlYXNlZDogdHJ1ZVxuICAgICAgICB9XG4gICAgXVxufTtcblxuXG4iXX0=

如果了解一定的逻辑的话就会发现其实下来node服务执行以后,就可以通过global['__coverage__'] 获取到相应的覆盖率数据。 再然后的内容就不继续说了,可以看下前面提到的知识储备中的文章,怎么去生成报告。 或者看下demo中的步骤也是可以的。

IM的运行中插桩的尝试

在上述的nyc的怎么过程中我们发现整体的过程很不方便,首先是是编译前插桩这个动作,再来就是覆盖率需要自己采集以及报告生成。

所以我们这个时候可以考虑下IM了。

IM 提供了以下的功能

  • hook了require()的方法,实际上就是被 require 的文件都会插桩。
  • 可以通过接口导出覆盖率的数据
  • 允许重置覆盖率的数据
  • 允许用户下载覆盖率的报告

这里就不举例说明怎么使用IM的了,因为他的说明文档已经很详细了,关键就是使用 im.hookLoader() 这个api就可以了。

不过这里有一个需要注意的地方, IM hook的是require()的方法, 所以这个会导致一个问题就是引入IM库的那个文件没办法被插桩, 这个是需要注意的地方(这里是个人尝试总结的,如果有哪里不对的,欢迎批评指出)。

另外在使用IM的时候还发现另外的一个问题, 那就是IM针对es6的插桩是存在问题的,类似于这个issue Updating Instrumentor (so that it supports ES6) ,其实只要更换instrument的库即可,不过作者已经不维护了,所以代码也一直未合并。

nyc运行中插桩

经过上述的一些尝试, 又重新把目光放回了nyc上,既然istanbul已经不维护,而转到了nyc上,nyc这块肯定不单单只是运行前插桩这种方式的。所以尝试又重新在网上搜索了下,结果真的有了新的发现。 nodejs 测试覆盖度工具nyc(Istanbul)简介 在这篇文章中作者执行nyc的方式并不是与mocha等测试框架结合使用的。而是直接在启动服务命令增加了nyc。

带着这个希望,重新尝试了下,发现在启动命令前 加上nyc执行以后,等到服务停止执行后,就可以在coverage 目录下生成覆盖率的报告了, 只是这里有一点不好的就是一定要服务停止以后才能够生成报告。

所以我们需要方便些的方式: 就是支持实时动态生成覆盖率报告的, 所以就有了 nodejs-coverage-lib 这个库, 其实这个库的功能还是相当的简单的,就是通过express启动了一个服务,提供了一个报告下载的接口, 而其中的过程则是获取到全局的变量__coverage__ 存储到对应的目录下后,再直接通过nyc命令生成报告,压缩最后的报告目录提供下载即可。

总结

以上就是关于nodejs这块覆盖率的一些调研以及总结。

  1. 通过nyc运行前插桩的方式进行获取到覆盖率数据,只是步骤有点小麻烦
  2. IM的运行时插桩的方式。只是可能存在es6插桩的问题以及入口文件无法获取到覆盖率的问题
  3. nyc 运行时插桩的方式目前来看是最推荐的方式了。并且通过文中的第三方库,可以省去很多过程中的步骤。

nodejs这块的覆盖率这块相对于前端来说还是会方便很多,因为主要还是覆盖率的数据就是在服务端处,免去了很多在用户端采集的过程了。

PS: 这里的覆盖率验证只是找了两个项目做了尝试,并不一定适用所有的项目(比如说typescript的项目)。

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:44:36  更:2021-08-10 13:45:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 20:38:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码