cenfun / monocart-coverage-reports

A code coverage tool to generate native V8 reports or Istanbul reports.
MIT License
31 stars 5 forks source link

[Bug] 没有执行的代码却被错误标记为已执行 #63

Closed fanksy closed 1 month ago

fanksy commented 1 month ago
Screenshot 2024-07-23 at 17 53 49

isIOS 方法执行字节偏移量为7519 -> 7585,图中选中部分是被执行的

export const isIOS = () => {
  if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
    return true; //没有执行
  }
  return false; //已执行
};

return true 这行没有执行,却被标记已执行

v8原始数据并没有标记return false是被执行的,这个是否算是v8的问题。

isIOS被调用4次,每次返回都是false,另外一个文件调用了isIOS方法,也被错误标记为执行,诡异的是bytes数据为空,如下图:

Screenshot 2024-07-23 at 18 03 13

发现被编译优化了

Screenshot 2024-07-23 at 18 18 12
cenfun commented 1 month ago

是这样的。 V8覆盖率数据针对的是编译过的代码,也就是

!!/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)

这个被执行了,至于 分支return true;已经不存在了,虽然源码存在,但只是通过soucemap还原到这个位置 如果没有位置可还原,则默认是标记成覆盖的。显然return true;这个没法还原,所以标记成了覆盖 从理论上说不应该这样的,但其实也无伤大雅,这里覆盖与不覆盖都不会出什么问题。

就如同写if(false){}, 会被编译器优化,从而标记成覆盖,理论上永远都不会覆盖,但这样的代码,覆盖与不覆盖都没有意义,可以使用上比如eslint的一些rules,在开发的时候就剔除掉,比如你上面的那个代码,eslint会推荐写成!!这样的

fanksy commented 1 month ago

这个可以理解,但是另外一个文件调用isIOS的情况,就需要深究了

Screenshot 2024-07-24 at 00 36 28
  useEffect(() => {
    if (!src) return () => {};
    const rawFunc = player.current.actions.toggleFullscreen;
    player.current.actions.toggleFullscreen = (e) => {
      rawFunc(e);
    };
    // 在app内部就隐藏苹果全屏按钮
    if (isApp && isIOS()) {
      document.querySelector('.video-react-fullscreen-control').style.display = 'none';  //这行没有执行
    }
  }, [src]);

isApp为true 但isIOS为false 而且查了报告数据,bytes数组居然为空

cenfun commented 1 month ago

分享下如何debug,快速定位问题。 首先,上面的截图我们看到的都是源文件的覆盖情况,也就是通过sourcemap转换位置后的情况 其实sourcemap转换本身也可能存在问题,而且问题还不少

你这个得查一下原始覆盖情况,看看是不是sourcemap转换的问题,一般来说原始覆盖情况都是非常精准的 如果转换没问题,那就是V8覆盖率本身的问题(如果是nodejs,某个node版本比如20.10好像就出现了V8覆盖率本身的问题,而且一直没有修复,但浏览器里似乎还没有遇见过)