51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 661|回复: 0
打印 上一主题 下一主题

[转贴] 全栈代码测试覆盖率及用例发现系统的建设和实践(上)

[复制链接]
  • TA的每日心情
    无聊
    4 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-7-13 09:35:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     1. 背景
      随着项目不断深入迭代,业务逻辑以及用户场景日渐复杂,补充和维护单元测试维护的成本也变得越来越高。测试覆盖质量通过测试用例评审或者人工 Code Review 的方式费时费力,单凭多方沟通和经验累积的方法,往往不够准确,也难以避免开发人员存在在代码上线前“夹带私货”的场景,并且没有量化的、直观的客观数据来支撑。
      为了在有限的时间及人力成本内保证项目质量,实现对项目质量的精细化管理,我们研发了 Finder —— 全栈代码测试覆盖率及用例发现系统(下文简称 Finder),通过精确化的数据量化代码质量,从而实现精准化测试。本文将介绍 Finder 的总体架构,以及它作为质量保障体系中的重要一环,如何在项目中实现精确化测试。
      2. Finder 项目介绍
      Finder 主要分为两个模块,一个是测试过程中对代码测试覆盖率进行收集与统计,一个是分析代码和用例的映射关系,精准确定回归测试范围。

    代码测试覆盖率统计模块,能够满足多环境、多需求、多服务的复杂测试场景,实时收集测试过程中的覆盖率信息,并生成覆盖率统计报告;其支持多端语言接入(Web、React Native、Golang),实现前后端项目全覆盖,打通整体研发流程。

    相关用例发现模块,针对变动的代码分析函数调用关系,追溯完整的调用关系链路,标记出所影响的 API 接口及相关用例,确定测试回归范围。
      3. 架构设计

    Finder 分为代理层、应用层、核心服务层三个模块:
      代理层 Finder Agent,负责前期数据采集的工作,包括编译阶段的代码插桩、覆盖率数据的采集、解析源码函数调用关系信息等;
      应用层 Finder Platform,包含需求信息管理、分支信息管理、单文件覆盖率染色图展示、API 信息展示、测试用例关联、函数调用链展示等页面模块;
      核心服务层 Finder Server,其中,覆盖率分析和服务调用分析是最主要的两个模块:
      覆盖率分析,对收集到的覆盖率数据进行数据聚合、差异增量分析、数据修正等操作;
      服务调用分析,将源码解析工具传输来的数据进行数据结构转换后,完成调用拓扑图生成、API 信息关联、测试用例发现等操作。
      在前期完成数据采集的接入工作后,测试人员无需额外操作,正常进行业务测试,测试完成后可以在可视化平台中查看覆盖率数据、相关测试用例等信息。
      4. 实现方案
      4.1 代码测试覆盖率模块

    代码覆盖率模块主要分为两个步骤,第一步是通过对项目源码插桩,采集覆盖率信息;第二步是对覆盖率信息进行分析,通过可视化平台展示统计报告。
      步骤一:插桩与数据采集
      代码插桩,意为在程序中插入一些代码,用于跟踪被测程序的某些信息。对于覆盖率测试而言,插桩的目的是检测程序中可执行语句被执行(即被覆盖)的情况。
      Finder 支持 JS 和 Golang 两种程序语言的代码覆盖率统计,接入成本低,对业务需求无侵入性。
      对于 JS 程序,我们在 babel 编译阶段进行插桩操作,注入到全局对象 window 中。我们提供了上报覆盖率数据的 npm 包 —— coverage-report,前端应用接入后会主动上报数据到 Finder Server;
      Golang 程序的覆盖率接入对业务项目零侵入,只需要引入 Finder Agent —— 覆盖率收集工具:它在编译阶段对源码插桩,包括 Git 信息和覆盖率信息注入;插桩完成后的服务会启动一个统计覆盖率的 Http Server,Finder Server 通过该 Http Server 提供的接口定时请求覆盖率数据。
      步骤二:差异覆盖率统计
      比起全量代码的覆盖率,实际上我们更关心改动代码部分的覆盖率情况。可以通过 Git 指令对比功能分支与 master 分支的代码差异,过滤无关代码,只针对改动代码部分进行覆盖率统计。
      为实现差异覆盖率的计算,我们约定以行(line)作为维度的结构表示 Git 代码差异和覆盖率信息,满足两者一一对应的关系。

    首先将 Git 分支对比得到的 Diff 数据转换成以代码行作为索引的数组格式,元素的值有空值和 + 两种枚举值:
      空值代表没有改动;
      + 代表有改动。
      覆盖率数组也转换成以代码行作为索引的数组格式,元素的值有 -1、0、1 三种枚举值:
      -1 代表无需统计覆盖率的代码(例如空格,注释等);
      0 代表未覆盖的代码(尚未执行);
      1 代表已覆盖的代码(已被执行)。
      将 Diff 数据与覆盖率数组进行合并,将非改动代码的覆盖率值置为 -1。得到最终的差异覆盖率数据。

    关键问题一:数据源标准化
      由于不同程序语言上报的覆盖率数据结构都不一致,我们需要将数据源标准化,统一转化以行(line)为维度的数组结构。
      首先,前端应用上报的覆盖率数据包含三种维度的覆盖率数据:
      Statement Coverage:语句维度的覆盖率数据;
      Branch Coverage:条件维度的覆盖率数据,例如 if/else、switch、三元运算符等;
      Function Coverage:函数维度的覆盖率数据。
      对于这三类覆盖率,我们做出以下数据转换:

    我们采用与操作将三类覆盖率数据合并为行覆盖率,即一行代码满足三类覆盖率才算被执行过。
      而后端 Golang 服务采集的覆盖率数据,如下图。


    同样,我们也需要将其转换为行维度的数组结构。











    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-25 05:54 , Processed in 0.065060 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表