文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

代码级质量技术之基本框架介绍

admin

admin

2023-06-06 17:32

关注

一、背景

代码级质量技术:顾名思义为了服务质量更好,涉及到代码层面的相关技术,特别要指出的是,代码级质量技术不单纯指代码召回技术,如静态代码扫描、单元测试等。

研究代码级质量技术主要有以下几个方面的原因:

1、随着精准测试等概念的兴起,对代码覆盖率的依赖逐渐加重,代码插桩的性能、准确性、时效性等都成为业界要解决的难题;

2、随着智能化,尤其是基于风险驱动的测试发展,对代码的理解需要得到突破,才能更好的从代码实现中挖掘风险、判断风险;

3、在黑盒级别的测试,质量工作者往往是通过对象的返回或外在表象观测对下的异常表现进而发现问题,但是其实可能很多潜在的异常并没有到 “肉眼” 可观测到的级别而导致问题漏出,这时候就需要有更多的对象更细的运行数据来供质量工作者分析去发现问题的蛛丝马迹,诸如:内存泄露、性能恶化等,所以业界有很多 prof、火焰图、asan 等偏白盒动态检测问题的技术出现;

4、代码作为产生实际问题最前沿的阵地,大部分问题都可以归因到某段代码不合理,如果可以在代码级别直接召回问题,无论从仿真复杂度、修复成本、定位成本等均会得到极大改善;

5、代码是工程师交流的舞台,通过对代码级质量技术的研究和规范,可以促进代码更加的具备鲁棒性和更优质的设计如单测提升可测性等,也可以促进质量保障人员对代码加深掌控与理解,进而在质量保障各类场合发挥关键作用。

从指导质量行为、极大提升召回问题能力、增强代码鲁棒性、提升人员对代码的掌控力等多个方面,都可以看出代码级质量技术的关键且不可替代作用,百度质量效能平台于 2019 年开始关注和投入该方向,在代码理解、代码探针、代码质量技术应用等多个层级多方面进行探索和落地,接下来的文章中会依次为大家介绍。

二、代码级质量技术架构

要理解代码级质量技术的原理和后续的主要应用场景,首先要理解代码从语言到可执行态的基本过程,下面以 C++ 为例说下基本过程:

C++ 从代码到可执行 bin 文件,主要分为四个阶段:预处理、编译、汇编和链接。

预处理:处理一些 #号定义的命令或语句(如 #define、#include、#ifdef 等),生成.i 文件;

编译:进行词法分析、语法分析和语义分析等,生成.s 的汇编文件,大家熟悉的 AST 抽象语法树就在该过程产生;

汇编:将对应的汇编指令翻译成机器指令,生成二进制.o 目标文件;

链接:链接分为两种,静态链接:将静态链接库中的内容直接装填到可执行程序中;动态链接:只在可执行程序中记录与动态链接库中共享对象的映射信息。

代码级质量技术的技术原理,主要是获取到该过程的代码片段数据或植入对应的目标代码,来达到对应的质量目标,如获取片段数据可以用来理解代码判断风险,可以用来指结构化代码结构,供自动生成单元测试和代码检测提供基础数据;如植入对应目标代码,可以用来做插桩(即覆盖率采集)或动态数据采集等。

基于上述介绍与理解,我们把代码级质量技术划分大范围为两个层次,两个层次内包含多个层次,如下图所示:

大层次一:代码理解,CodeC(Code Comprehend):偏底层技术,基于底层 AST 等能力、分析出代码的特性(AST、调用链、依赖等)和风险度,通过 API、SDK 等方式对外提供基础服务

该层会遇到众多技术挑战,如要适配不同语言的解析器、编译过程;基础框架进行代码调优;分析过程数据缺失修复等,是一项非常细致且有技术挑战的工作,当然我们在该过程也会探索出一些技术经验供大家参考。

大层次二:代码级质量技术应用,Codeπ:主要是依托代码理解的过程或产出,植入对应的信息,以达到对应的质量目标,这个层次应用场景是关键,因此我们是以解决问题的目标为导向,对该层次进行细分,所以目标或应用场景的不同会使得该层次的分类会不断增加,目前分为以下四类:

下面的章节我们会分布从第二级的层次,为大家做基本原理和过程介绍,后续还会有系列发文再深入的介绍对应实现内容。

三、代码理解层介绍

代码理解是一个以软件程序为对象,对其内部的运作流程进行分析,获取相关的知识信息,这些信息可以用于软件开发、软件测试、软件维护等各个阶段,旨在对程序进行性能优化和正确性验证。代码理解常用的分析方向有静态分析、动态分析、非源码分析 3 类,但是随着 LLM 大模型的发展,我们也正在研究模型在代码理解领域的突破与应用。

静态分析:是指在不运行代码的方式下,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,验证代码是否满足规范性、安全性、可靠性、可维护性等指标的一种代码分析技术。

动态分析:软件系统在模拟的或真实的环境中执行之前、之中和之后,对软件系统行为的分析。

非代码分析:主要是对数据文件、配置文件等非源码文件和源码间进行关联分析,当代码仓变更时,能感知变更内容对源码、功能的影响。

动态分析多为对程序进行的一些功能测试或性能测试等对程序的运行结果,资源使用情况的相关程序分析工作。故本小节主要介绍静态程序分析相关的代码理解技术,不对动态程序分析做展开。

静态程序分析在不执行程序程序的情况下对程序进行分析,分析的对象可以是针对特定版本的源代码或者二进制文件,通过词法分析、语法分析、控制流、数据流分析等技术对程序代码进行扫描,根据不同的分析目标,得到对应的分析结果。在学术界和工业界主要应用在软件安全领域,验证代码是否满足规范性、安全性、可靠性、可维护性;在百度内部,除漏洞检测外,静态程序分析还包括多维度的代码分析和度量手段,在交付系统和监测系统中被广泛使用。

业界静态分析一般基于以下 4 种方式展开:

常用的静态程序分析技术:

四、代码级应用之探针

代码探针,也是插桩技术,它是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为 “探测仪”,本质上就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法。

不同语言的插桩技术有所不同,常见的技术有:ccover、covtool、jacoco、gocov。

CodeP 代码探针可以应用在:代码监控(方法执行耗时等),代码分析(函数、数据流的跟踪等),业务埋点。

除此之外,代码探针最常见的场景是代码覆盖率采集。

4.1 覆盖率

代码覆盖率,是软件测试中的一种度量,描述程序中源代码被测试的比例和程度,所得比例称为代码覆盖率 ,分析未覆盖部分的代码,从而反推在前期测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点。覆盖率统计的分类包含:

行覆盖率:行覆盖率是最基本的指标,表示是否代码中的每个可执行语句都被执行过;

分支覆盖率:分支覆盖使用一组测试参数来测试是否代码中所有的分支都能被测试到了;

路径覆盖率: 对包括所有分支在内的所有的路径都能测试一遍,这就是路径覆盖;

变更行覆盖率:上一次发布代码后更新的代码的行覆盖率,这个数据可以方便的看出新的代码是否做了测试。

覆盖率的业务使用场景广泛比如:RD 自测、RD 准入、QA 准出、外包评估、精准测试、集成测试、基线升级评估、灰度测试评估,自动化测试能力评估、众测等。

代码探针实现覆盖率统计的步骤如下:

1、识别待插桩的函数

2、用 codep 技术对函数进行插桩,插桩技术分为:

3、探针采集覆盖信息整合,统计覆盖率数据

五、代码级应用之召回

从召回异常问题的角度介绍两类代码级技术应用:智能 UT、SA。与现有异常测试方法进行对比分析,压力测试、功能测试依赖编译运行且需人工构造异常场景,存在高成本、低召回的问题。而智能 UT 和 SA 基于白盒分析产出的数据可以提前、快速、低成本、轻量级地召回异常问题。

5.1 智能 UT

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证,这里的最小测试单元是指函数或者类。在问题召回层面,UT 针对最小单元进行测试,构造数据简单、易于验证正确性,便于后续功能的回归,能够更早地发现问题,定位和解决问题成本低。

传统 UT 依赖开发人员人工编写单测代码来进行测试,存在开发成本高、依赖人的意识等缺点。基于单测的基本原理衍生出了智能 UT 工具。智能 UT 通过自动的分析函数和随机的构造测试数据,可自动生成异常单元测试代码,生成的代码可以直接用于单元测试任务,单元测试运行后,智能 UT 工具能分析代码中存在的稳定性问题。

如下图展示,智能 UT 建设的主要思路是将一个开发人员编写单元测试代码的过程进行拆解,将整个过程抽象为确认待测试函数 -> 分析代码 -> 构造测试数据 -> 生成测试代码四个步骤,利用白盒数据和一系列算法模拟上述单测代码生成的过程从而自动地生成异常单元测试代码并应用于单元测试任务。

△UT 与智能 UT 过程对比

5.2 SA - 基于规则的代码缺陷检测

SA(static analysis)意为静态代码扫描,整个扫描过程无需编译运行,仅通过词法分析,语法分析,语义分析等技术对代码进行扫描,进而发现代码逻辑错误和编程缺陷。依据编程语言的自身特性,可将各类风险场景提取转化为通用的规则进行异常拦截。现有 SA 检查是通过依赖代码分析、基于通用的风险规则进行代码缺陷检查的静态代码扫描工具,可召回例如空指针访问、数组越界、除零等风险问题。

下图展示了基于规则的静态代码检查处理流程。

△SA 处理流程框架

优点:无需编译运行、资源消耗少,扫描分析过程高度自动化、不依赖人力。

缺点:依赖后验知识、存在滞后性,依赖人开发规则、准召低、可持续性差。

此外在代码级领域还有专门被测对象动态行为的检测技术,用于发现程序细微的异常,比如业界常用的火焰图、gprof、ASAN 等工具,就是在程序运行时收集程序表现数据,用于检测程序异常问题。

六、代码级应用之孤岛函数识别

6.1 什么是孤岛函数

不被调用的函数被称为孤岛函数。如果一个函数已不再被调用,就成了无用的废弃函数。

6.2 为什么要做孤单函数识别

无用函数属于技术债治理的场景之一,无用代码的存在增加了软件开发、测试、以及问题排查的开销,例如 QA 和 RD 需要更多额外的精力来评估需求的影响范围。

通过孤岛函数识别的能力可以做无用代码和相关用例、配置、数据的清理,提升代码可维护性,同时提升问题的排查效率。

6.3 如何识别孤岛函数

1、静态分析方法

原理:通过函数调用分析,获取入度为 0 的函数,再结合不同语言特性,筛选出实际未被调用的函数。例如:c++ 语言中构造函数等非显式调用的函数、纯虚拟函数等函数特性。

2、动态分析方法

原理:通过探针的方式,在程序运行时对函数调用栈进行记录,一般是基于抽样或者开关的方式来控制。

3、动静结合方法

将上述两种方法结合起来时使用,进行能力互补。

这篇文章更多的是从背景、结构和各个层的基本概念介绍了代码级质量技术的概况,接下来的文章将会在各个方面、各个层级进行展开,欢迎大家关注和一起探讨。


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯