写点什么

知乎质量平台的设计和实现

  • 2019-06-20
  • 本文字数:2880 字

    阅读完需:约 9 分钟

知乎质量平台的设计和实现

背景

质量保障团队持续推进知乎质量体系的建设,发起和参与了一系列的工作,包括但不限于:


  • 产研流程规范

  • 专项测试

  • 持续集成流水线建设

  • 小黑屋和众测机制

  • 内测和灰度

  • 线上质量问题监控

  • 客户端质量大赛


其中的每一项工作都产生了大量质量数据,这些数据不仅可以用来衡量 QA 团队工作的效果,我们还可以通过质量数据的发布进一步增强其他团队质量意识,更好的建设全公司的质量文化。


在早期,我们通过写脚本或人肉统计的方式从各内部系统上拿到需要的信息,在 excel 上以图表的形式将这些质量数据展示出来。虽然这种方式偶尔会出错且耗时较长,但成本还可以接受。随着公司业务的快速发展,QA 团队人数也迎来了持续快速增长,并按照事业部分成了不同的小组。与此同时,我们还面临着知乎客户端的迭代周期从两周缩短到一周以及 客户端组件化 的挑战,质量数据的收集、统计、展示需要投入越来越多的时间和精力,靠人工整理出完整、可靠、可视化的质量数据,几乎是不可能完成的任务。我们迫切地需要一个能够自动收集、处理、展示各种类型数据的质量平台,而结合整个 QA 团队的实际工作,我们决定最优先实现客户端每个版本需求和 Bug 情况的自动收集和展示。

总体设计

如前文所述,质量平台的初步目标包括如下两点:


  • 每个客户端版本每个事业部的测试报告尽可能自动生成

  • 质量数据变化趋势高度可视化


依照初步目标,质量平台应该包括如下三大模块:


  • 数据收集:自动从各个系统收集基础数据

  • 数据处理:将基础数据关联起来,组合成测试报告,同时支持人工录入无法自动获取的部分信息

  • 数据展示:以图表的形式展示各项质量数据随版本变化的趋势

数据收集

测试报告的主要内容是该客户端版本上指定事业部完成的需求和发现的 Bug 统计,那么我们获取的基础数据分为以下几类:

版本信息

版本是测试报告的基本维度,对于知乎客户端来说,一个版本的整个生命周期分为 开发、测试、灰度、上线 这 4 个阶段,测试报告需要记录每一个阶段的代码提交和 Bug 情况,因此需要明确每个阶段的边界。


目前知乎客户端发布流程中,有三项重要的操作:


  • 拉分支:知乎客户端 Gitlab 的项目中存在一个名为 develop 的分支,所有新功能都只能提交到这个分支上,到达集成测试的时间点时,我们会基于 develop 分支创建一个新的 Release 分支,这个新分支的创建就是版本从开发阶段进入测试阶段的标志,而测试中发现的 Bug 都会修复在新分支上

  • 发灰度:在测试阶段经过完整的回归测试和 bugfix 之后,我们会发布一个灰度版本给我们邀请的内测用户试用,灰度版的发布就是测试阶段进入灰度阶段的标志

  • 提审:经多次灰度验证版本质量合格后,提交应用市场审核,提审操作完成后,会收到由应用市场或负责应用市场推广的同事发出的邮件


综上所述,每个阶段的边界可以总结为下表,质量平台会根据这些条件判断某个版本所处阶段



事业部信息


事业部同样也是是测试报告的基本维度,但需求和 Bug 信息并没有直接的与事业部关联的方法,质量平台最终通过需求和 Bug 的负责人信息间接找到对应事业部。


对于每一个需求或 Bug ,都有唯一一个明确的开发负责人,拿到这个负责人之后,质量平台会请求知乎内部的通讯录,从而获取负责人所属事业部信息,该事业部记录为需求或 Bug 所属事业部。

Bug 信息

知乎内部用 JIRA 作为 Bug 管理工具,当 QA 创建或更新一个 Bug 时,JIRA 会通过我们事先配置的 webhook 将这个 Bug 的全部信息发送给质量平台,质量平台会从中提取所需的信息存储在数据库中。


QA 组内对 JIRA 上的 Bug 填写有明确规范,需要准确填写 Bug 所属客户端版本、发布阶段、事业部等信息,这样质量平台就可以根据这些规范自动将 Bug 与测试报告对应起来。

需求信息

知乎内部使用 JIRA 作为需求管理工具,但由于每个事业部需求管理方式差别较大,质量平台无法像 Bug 信息一样自动收集和匹配 JIRA 上的需求。


因此我们转而收集每个版本的代码提交信息,由于客户端的每次代码提交都已经要求关联对应的 JIRA 上的 issue(包括需求和 Bug),我们可以间接获取每个版本的需求信息。

代码提交信息

知乎内部使用 Gitlab 作为代码管理工具,由于知乎客户端正在组件化重构过程中,目前代码变更的提交有两种方式:向主仓库提交 MR 和通过 组件管理平台 升级组件版本号。


当工程师通过 MR 提交代码时,我们预先配置的 webhook 会在 MR 合并时给质量平台发送消息,消息中包含 MR 代码改动量、负责人、合并时间、目标分支等信息,通过合并时间+目标分支,可以定位到这个 MR 属于哪个版本的哪个阶段,通过 MR 作者信息可以定位到这个 MR 属于哪个事业部。由于 Gitlab 支持 与 JIRA 的集成,知乎工程师会在 MR 标题中填写 JIRA 上 issue 的 ID ,我们可以通过这个 ID 将 MR 与 JIRA 上的需求或 Bug 关联起来。


当工程师通过组件管理平台提交新的组件版本时,会被要求填写如下信息,而在测试通过后并升级提测组件时,组件管理平台会将这些信息加上升级时间等信息发送给质量平台。质量平台就可以通过升级时间+主工程分支定位到这次组件升级属于哪个版本的哪个阶段,通过提测操作人信息可以定位到这次组件升级属于哪个事业部。

数据处理

有了上述的各项基础数据,我们可以很简单地将它们组合成指定版本指定事业部的测试报告,报告中某一个版本阶段的报告内容如下图所示,其中 Diff 指组件升级:



同时,将同一个版本的每个阶段数据累计,可以得到如下的版本总体数据:


除了这些自动收集的数据,测试报告还支持手动填写 Bug 。在「Bug 列表」中点击「添加」按钮,可以通过填写jql 在指定的版本阶段添加 JIRA 的任意 issue 。

数据展示

为了快速实现需求并降低维护成本,我们决定使用开源的 BI 系统来实现数据的展示,并对几款市面上比较优秀的产品进行了调研:



综合以上优缺点,我们最终选择了 MetaBase 作为平台数据可视化系统。


值得一提的是,为了配置的灵活性,我们使用 MetaBase 提供的「原生查询」功能(即通过 sql 获取报表中的数据)。同时,我们在做数据库设计时,故意为每张表增加一些冗余信息,这样可以降低 sql 查询语句的复杂度以及减少 join 操作,从而降低查询时间。


基于收集到的基础数据,我们可以在 MetaBase 上做出各维度的质量数据趋势图

尾声

本文介绍了知乎质量平台的设计思想以及实现方案,解决客户端版本质量数据收集和展示的问题。知乎质量平台从 2018 年 9 月投入使用至今,已记录多于 50 个客户端版本的质量数据并生成百余份客户端版本测试报告。


除此之外,经过不断的迭代,质量平台目前还支持了产品质量周报、需求维度测试报告、线上故障报告等多种类型的报告,同时进一步收集了客户端启动时间、网络请求响应时间、包体积等数据,帮助其他技术团队更准确地制定工作计划。我们会在后续文章中对这些功能进行详述。有了质量平台的支持,QA 团队的工作效率得到了明显的提升,质量平台提供的各项数据,也为各事业部和整个知乎的质量文化建设工作提供了有力的支持。


最后,知乎质量保障团队的工具平台小组持续招聘中,若你对持续集成、持续交付、移动端组件管理、质量平台等工作有兴趣,欢迎点击 这里 查看职位详情,期待你的加入!


本文转载自知乎


原文链接


https://zhuanlan.zhihu.com/p/68059263


2019-06-20 08:0012725

评论 1 条评论

发布
用户头像
superset 支持自定义SQL,并支持自定义SQL转换成图表
2020-09-09 12:02
回复
没有更多了
发现更多内容

【架构实战营】模块八

衣谷

架构实战营

【CSS 学习总结】目录 - CSS 知识点梳理

Brave

CSS 12月日更

开始了解DevSecOps 1

搬砖的周狮傅

DevSecOps

Flutter开发小技巧【Flutter专题23】

坚果

flutter 28天写作 12月日更

React进阶(十一):create-react-app脚手架关闭 eslint 提醒

No Silver Bullet

React 12月日更 creat-react-app

花一点时间优化一次年迈的后台系统的检索体验

为自己带盐

28天写作 12月日更 ​jQuery

语音信号处理 4:语音信号在时域和频域的表示

轻口味

28天写作 12月日更

什么是VLAN?如何配置?VLAN间路由又是怎样的?一文了解!

Ethereal

VLAN 网络技术

【LeetCode】一年中的第几天Java题解

Albert

算法 LeetCode 12月日更

React进阶(十二):HOOK

No Silver Bullet

React Hooks 12月日更

【架构实战营】模块七

衣谷

架构实战营

Istio的认证授权机制分析

xcbeyond

istio 认证授权 28天写作 12月日更

念叨了一年的游戏叙事书中文版终于出了!

博文视点Broadview

vivo:不做开发者的过客,变成IoT的归人

脑极体

DDD领域驱动设计实战(三)-深入理解实体

JavaEdge

12月日更

NGINX从入门到实践-基础篇

小志Codings

nginx Python3

面试官:HashSet如何保证元素不重复?

王磊

synchronized源码分析之锁的膨胀

Ayue、

synchronized 锁机制 锁升级

解决:Command ‘mongo‘ not found, but can be installed with

liuzhen007

28天写作 12月日更

50 K8S之Contour控制器

穿过生命散发芬芳

k8s 28天写作 12月日更

Python 自动化领域起点篇,Selenium WebDriver 学习第1篇

梦想橡皮擦

12月日更

Kvrocks 在 RocksDB 上的优化实践

Kvrocks

Redis 协议

Dubbo框架学习笔记七

风翱

dubbo 12月日更

[Pulsar] Consumer消费

Zike Yang

Apache Pulsar 12月日更

20《重学JAVA》--集合(二)

杨鹏Geek

Java25周年 28天写作 12月日更

怎么活的超脱:把自己的生活看成一场戏

mtfelix

28天写作

元宇宙100讲-0x007

hackstoic

元宇宙

如何实现Redis限流

喵叔

28天写作 12月日更

如何用Docker Compose部署项目?

秦怀杂货店

Docker springboot

Android EventBus 集成问题小结

阿策小和尚

28天写作 Android 小菜鸟 12月日更

dart系列之:手写Library,Library编写最佳实践

程序那些事

flutter dart 程序那些事 12月日更

知乎质量平台的设计和实现_语言 & 开发_钟离无糖_InfoQ精选文章