• 有点麻烦 除非你自己去改 jacoco 的源码,因为 jacoco 的源码逻辑是根据 classId 进行合并的,不是按照 className 进行合并的,所以你虽然两个类包名类名都一样,但是 classId 是不一样的。我们自己是做了二次修改,根据 className 做了一次合并处理

  • 这个 cookie 信息是否有有效期呀。看样子就像是 cookie 失效了呀

  • jacoco 就很通用了呀,我们这边都是用它

  • @rocky 你微信多少 可以聊下,

  • 首先你得清楚下其他的模块是否是对应到你的启动的服务中。因为多模块的项目可能对应的是多个服务。如果 jacoco 里面都有其他模块的数据。那么只是你报告生成逻辑的问题

  • 我们现在基本都是看增量的报告,增量 如果是手工测试,覆盖率应该在 70% 以上,然后如果是接口测试那么在 80% 都是自己拍脑袋定的。

  • 另外现在 ios 移动端都没有红点提示我有未读消息了

  • 是的

  • 帖子里面仅楼主可见貌似有问题,我就是楼主呀

  • 你的多少 我加你 可以交流的 哈。

  • 抱歉 上次我跟你说错了,

    "parser-plugins": [
            "typescript",
            "jsx",
            "asyncGenerators",
            "bigInt",
            "classProperties",
            "classPrivateProperties",
            "dynamicImport",
            "importMeta",
            "objectRestSpread",
            "optionalCatchBinding",
            "decorators-legacy"
        ]
    

    应该是这个才对,用 decorators-legacy

  • 或者你能不能提供一个单独的文件处理 针对他插桩试试看 ,如果不行能方便去掉一些敏感的代码 拿出一个文件 我们来看下?

  • 你不能这么搞的 你这么处理的话就相当于 你的 babel 的 parser 只是用的装饰器那个插件的。复制下我这个吧

    "parser-plugins": [
            "typescript",
            "jsx",
            "asyncGenerators",
            "bigInt",
            "classProperties",
            "classPrivateProperties",
            "dynamicImport",
            "importMeta",
            "objectRestSpread",
            "optionalCatchBinding",
            "decorators"
        ]
    

  • 加个 decorators 可以解决的。 你是用的 nyc 插桩吧

  • 你微信多少? 我没怎么用 istanbul-middleware 不过可以一起看看

  • 但是你这个匿名函数会有啥影响吗?或者方便的话 加个微信聊下?

  • 没有遇到过,不过可以分享下那个函数怎么样的吗,我这边也试试看?

  • 是的 ,你可以看下这个 issue 最后解决的内容,Fix printing TSTypeOperator token 那个被替换为 word 了。所以最后没有跑那个方法了。

  • 咦 我这边都显示正常呀。

  • 可以了解下 selenium ide 最新版本的录制工具,我记得上面能支持拖拽,右键的一些录制的

  • cypress 那块更多的是基于自动化的方式的,但是它里面的实现逻辑是可以参考的。
    增量这块我们其实也做了,但是我们目前只是做到了基于文件的情况,就是这个文件被修改到就要求被覆盖,还没有继续完善到基于行或者方法的覆盖率这种。


  • 更新于 2020.07.20

    前端代码覆盖率又接入了新的项目,但是这次的前端用到了一个新的框架 easywebpack, 不过好在官方的文档是相当的详尽,所以在babel 升级基本没有遇到什么大的问题。

    原以为一切的会比较顺利的进行, 但是测试的同事反馈说出现几个文件的覆盖率数据明显不正确,并且那几个文件的数据都是一样的。我们来看下结果数据
    image

    这里的四个覆盖率数据竟然是完全一样的,我们再详细看下某个文件的详细覆盖率数据

    image

    很明显 从 11 行的地方我们发现这里的代码与覆盖率的数据其实是完全对应不上的,我们在 11 行处根本就不存在有 IF 的代码逻辑。

    那现在的问题来了为什么会出现这种情况呢? 首先我们的覆盖率数据是有经过多次合并的,所以首先我们可能要怀疑是我们的覆盖率数据合并导致的问题。那我们就先验证下原生的网页上的覆盖率数据是否有问题吧

    image

    这里是从浏览器的控制台打印出来的结果,从上述的一些数据我们可以看出来,在 11 的时候,确实有一个 if 的语句,所以说明了一个问题 就是原本的文件覆盖率数据就已经错误了。

    那问题到底出在哪里呢?这里还是需要从打包的地方去分析这个问题了。

    以下是 webpack 的部分截图

    image

    这里分别了客户端渲染以及服务端渲染的打包,所以我们要重点看下 loader.js 里面做了啥事情。

    module.exports = function() {
      this.cacheable();
      return `
        import React from 'react';
        import ReactDom from 'react-dom';
        import { AppContainer } from 'react-hot-loader';
        import Entry from '${this.resourcePath.replace(/\\/g, '\\\\')}';
        const state = window.__INITIAL_STATE__;
        const render = (App)=>{
          ReactDom.hydrate(EASY_ENV_IS_DEV ? <AppContainer><App {...state} /></AppContainer> : <App {...state} />, document.getElementById('app'));
        };
    
        if (EASY_ENV_IS_DEV && module.hot) {
          module.hot.accept('${this.resourcePath.replace(/\\/g, '\\\\')}', () => { render(Entry) });
        }
        render(Entry);
      `;
    };
    
    

    针对要处理的 js 文件,看起来这里的 loader 又重新进行 render 了一次,而且如果细心一点 我们可能注意到一个很关键的因素,这里从 return 方法往下的第 11 行 刚好是 if (EASY_ENV_IS_DEV && module.hot) { 一个 if 语句, 所以其实我们所有错误的 js 的覆盖率都被这段的逻辑所影响到了。那我们原本的 jsx 的文件有没有被插桩呢?所以还是需要看下插桩后的文件到底长什么样。

    针对 campCourse.jsx 的打包文件

    image

    我们在 6w 多行的时候可以看到有这样的一个方法 针对的就是该文件的覆盖率数据

    然后我们再观察
    image

    在 11w 多行的时候, 也出现了同样的覆盖率数据,而且该数据与我们从浏览器读到的数据是一致的也就是错误的数据。到这里应该就能有一定的总结的,也就是说源码文件其实是有被插桩的,只是说它的数据最终被另外一个相同对象给覆盖了导致我们拿到了错误的数据。

    问题到了这里就要想着怎么解决了,其实 istanbul 提供另一些方式来过滤掉一些你不想插桩的代码。具体可以看 ignoring-code-for-coverage

    所以我们需要做的是忽略到这个文件的插桩,不过这个 ignore 添加在哪里还是有一定的技巧的 我们来看下最后的改动代码吧。

    module.exports = function() {
      this.cacheable();
      return `/* istanbul ignore file */
        import React from 'react';
        import ReactDom from 'react-dom';
        import { AppContainer } from 'react-hot-loader';
        import Entry from '${this.resourcePath.replace(/\\/g, '\\\\')}';
        const state = window.__INITIAL_STATE__;
        const render = (App)=>{
          ReactDom.hydrate(EASY_ENV_IS_DEV ? <AppContainer><App {...state} /></AppContainer> : <App {...state} />, document.getElementById('app'));
        };
    
        if (EASY_ENV_IS_DEV && module.hot) {
          module.hot.accept('${this.resourcePath.replace(/\\/g, '\\\\')}', () => { render(Entry) });
        }
        render(Entry);
      `;
    };
    
    

    我们需要将/* istanbul ignore file */的 内容添加在 return 语句的后面,即第一行才行,如此下来的代码都不会被插桩处理了。

  • 哈哈,暂时没有考虑这个,不过很感谢😄

  • 这个我没有遇到过,如果你不嫌麻烦的话,可以弄一个最小的仓库内容出来 然后我帮你看看是什么情况,不然这样子描述 我帮不上什么忙

  • 看下 16 楼的回复,可以不回滚版本也是能解决那个问题的。