Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

预检测 -- 微店的前端质量保证探索 #153

Open
hoperyy opened this issue May 31, 2021 · 1 comment
Open

预检测 -- 微店的前端质量保证探索 #153

hoperyy opened this issue May 31, 2021 · 1 comment

Comments

@hoperyy
Copy link
Owner

hoperyy commented May 31, 2021

概念介绍

一般而言,项目的发布至少包括构建、部署、回归测试等环节:

  • 构建:对源码的转译、打包
  • 部署:将页面部署到生产环境
  • 回归测试:对已在生产环境的页面进行测试

预检测是一个自动化测试方案,指的是在项目构建后、部署前,对项目进行多方面的测试,发现并推动解决项目在代码质量、安全性、稳定性、性能等方面的问题。

和预检测对应的,是上线后的监控,也就是我们常见的各类监控平台。

预检测平台的位置

为什么要做预检测?

一句话描述:如果一些问题只能在上线后发现,就已经太晚了

举几个例子:

  • 如果构建产物含有非外网链接,而测试人员没有在内网环境下发现这个问题,导致项目上线,可能直接导致页面白屏
  • 如果构建产物含有未被 Babel 转译的代码,低版本浏览器未能识别 let、const 等语法,可能直接导致页面白屏
  • 如果构建产物含有安全漏洞,链接跳到了一些不可描述页面,公司业务可能有凉凉的风险
  • ... ...

以上的问题,如果人工仔细检查也是可以发现一些的,但实际情况往往是大家都很忙,一些风险极易被忽略。

那么,能否用工具化的方式对构建产物对一次体检呢?于是,我们结合自身业务情况,开启了预检测平台的建设。

预检测能做什么?

上文说了一些项目上线前可能有的风险点,预检测提供了系统性的工具化的解决方案。

或者说,“预检测能做什么?”这个问题,可以转换为另一个问题:”如何衡量预检测平台的功能水平?“。

先说结论,我们在微店自身业务需要的基础上,在项目构建后,部署前,对构建产物进行了如下预检测:

  • 代码规范
    • JavaScript 规范
    • Style 规范
    • 其他编码规范
  • 性能
    • js/css/img 等资源大小
    • 静态资源访问耗时
    • 图片裁剪检测
    • ... ...
  • 稳定性
    • 资源访问失败
    • 跨域问题
    • 链接合法性校验(如 /path//subpath 类的写法)
    • 页面是否白屏
    • ...
  • 安全性
    • 对 innerHTML 的直接使用
    • 对 outerHTML 的直接使用
    • 各类链接(<a>、<img>、<link>、<script> 等元素的链接)的合法性校验
    • ... ...
  • 埋点
    • 业务是否埋点
    • 埋点是否有效
    • 是否重复上报埋点
    • ... ...
  • 其他
    • 其他各类体验检测

可以看到,预检测可以检测从静态代码到运行时的项目表现,理论上,它可以将项目上线后的各类监控指标,前移到项目上线前,并且可以做的更多,让项目尽量少地带病上线。

预检测平台的设计架构

每个设计架构都是为了满足自身的业务需求的,对于微店而言,预检测要做到至少以下几点:

  • 灵活性:各类检测需要能够根据业务需求持续迭代
  • 可配置:不同特点的业务,所需的检测不尽相同
  • 快速性:预检测需要在尽可能短的时间内完成,避免对发布流程有明显影响

微店预检测平台设计了如下特征:

  • 插件化

    针对以上要求,微店的预检测平台采用了插件化的设计。

    和很多知名工具一样,预检测采用了”微内核“设计,预检测核心部分负责流程处理、任务调度,各类检测作为功能插件,按需引入。

    image

    image

    虽然社区内像 webpack、Babel 等均实现了插件化的设计(Tappable、babel-parser),我们也很难直接拿来使用,主要是以下原因:

    • Tappable 极其强大,也相对复杂,接入和维护成本较高
    • babel-parser 是针对 Babel 的插件化解析器,并无直接使用价值
    • ... ...

    在微店的插件化预检测平台的建设中,因为广泛使用了事件流串行与并行控制、async / await、异常处理等功能,我们开发了抽象的插件化底层工具 plugin-anything,以满足预检测平台的各类需求。

    plugin-anything 的设计如下:

    plugin-anything 设计架构

  • 静态代码扫描

    这点很明了,预检测平台可以拿到项目的代码信息,且可以对源码、构建产物执行扫描,完成各类和静态代码扫描相关的检测。

  • 运行时检测

    预检测使用 puppeteer 做运行时检测,并对运行时的各类表现进行监控,完成各类和运行时相关的检测(白屏、稳定性等)。

预检测平台的建设遇到了哪些问题?

预检测平台的建设并不是很简单的事情,我们遇到了一些问题:

  • 如何保证短时间内完成预检测

    预检测主要耗时在运行时检测上,尤其是对于一些大型项目(超过 50 个页面),其运行时检测如果不做优化的话,会及其耗时。

    微店的预检测针对运行时检测的效率,在不增加服务器的条件下,做了大量的优化,做到了 95% 的项目可以在 1 分钟内完成所有检测,具体方案值得另开分享或文章介绍,敬请期待。

  • 项目管理

    从上文可以看到,微店预检测平台的检测任务非常多样,而这些检测任务是作为插件独立维护的,和 Babel、React 一样,我们采用 monorepo 对预检测进行项目管理,预检测核心包和各类插件检测包作为子 package 置于一个大工程中。

    对于 monorepo 笔者就不做过多介绍了,社区内对其介绍的文章非常多。

  • 调试问题

    微店预检测平台有一个独立的 server 服务,而预检测功能有另外的工程独立维护,server 引入预检测功能包,那这里就涉及如何调试本地 server 和本地的预检测功能的问题。

    一般来说,server 引入预检测功能包的代码是这样写的:

    import pretester from 'pretester'; // 伪代码
    
    pretester.run(); // 执行

    为了方便调试,我们这样写:

    let pretester = null;
    try { 
        pretester = require('../pretester'); // 本地版本的检测功能包
    } catch {
        pretester = require('pretester');
    }
    
    pretester.run(); // 执行

预检测平台要做到什么程度?

学无止境,优化无止境。

听起来像是废话哈哈。最主要的是要满足或超过业务需求,总的来说,微店预检测平台的发展,是朝着”跑在业务前面“的宗旨建设。这就要求平台的建设者更主动地持续地思考如何更好地支持业务。

具体的,我们可以从以下目标持续建设预检测平台:

  • 速度:可以在 20s 内完成 50 个页面级的预检测
  • 覆盖率:可以发现 90% 以上的问题;测试覆盖面,可以涵盖上线后的监控指标的 90% 以上
  • 业务:持续深入了解业务中的实际场景,及时覆盖
  • 业务单测:预检测平台可以执行不同业务开发者的业务单测,提供更强大的检测功能

最后

预检测相对于监控平台而言,是一个相对较新的事务,但可以发现,它其实是前端或者项目开发者在长期的开发过程中遇到各类痛点的系统性解决方案,并不是新概念。

但带着”系统性“的持续思考的习惯,可以帮助我们发现并解决实际业务中的各类问题。

最后,微店前端持续招人,欢迎加入微店前端!

@hoperyy hoperyy changed the title 预检测 -- 微店的质量保证探索 预检测 -- 微店的前端质量保证探索 May 31, 2021
@liuyingbin1922
Copy link

点赞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants