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

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

  • 是的 ,你可以看下这个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楼的回复,可以不回滚版本也是能解决那个问题的。