前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >测试影响分析(TIA),让测试更快的技术

测试影响分析(TIA),让测试更快的技术

作者头像
DevOps时代
发布2018-02-02 14:47:42
1.5K0
发布2018-02-02 14:47:42
举报

构建过程中,测试影响分析(TIA)是一种加快自动化测试的新式方法。它的 工作原理就是通过获得新的代码变动,分析这些代码的调用关系图来判断应该调 用那些自动化测试用例进行自动化测试。微软已经在这个方法上做了大量的工 作,而且对于开发团队也可能有一些帮助。

现代软件开发中有很多让人头疼的问题,其中一个问题就是在代码真正上线之 前要完成非常多的测试。但是在执行过程中,开发人员会采用一种代价很高的应对策略,那就是不在自己的本地的工作站上面做任何测试,相反, 它们依赖于稍 后在集成服务器上运行的测试。当(shift right)状况出现,就会无可避免的掉进 无休止的代码修复中,不能自拔。

当然,预集成前进行的所有测试内容都应该在持续集成(CI)构建中集成后立 即进行测试。即使是最高级别的研发团队,在开发过程中可能也会遇到为了处理 严重问题而临时进行快速提交的情况。这些团队也可能有人在约定的集成过程中 希望“省事”,而不运行测试。幸运的是,CI 服务器和一系列标准化的构建过 程会很快捕获这些问题。

目前已存在的各种加速测试技术中,包括利用多个服务器运行不同的测试模 块,为那些慢速的远程服务提交测试替身(Test Double)技术。

但是, 本文将 重点讨论如何通过分析来判断最可能出现问题的模块,从而减少要运行的测试数 量。使用金字塔测试结构,我们会更频繁的运行单元测试,因为它们通常运行得 更快、质量更高,并且能够提供更具体的反馈。特别是我们构建了一组测试,在 集成前后这些测试会作为 CI 的一部分运行。然后我们部署流水线,运行金字塔 下面那些测试项。

同样的问题再次出现:如果测试快速无限次的运行,我们将一直运行所有的 测试用例。但实际上并不需要如此,因此我们在运行它们的时候需要平衡成本和价值。

在这篇文章中,我详细介绍目前计算机科学中一个新兴的测试领域,微软正在 引领这一领域,一个需要长期自动化测试构建的公司应该注意到这一点。如果您在.NET 生态系统中,您可能会立即受益于微软在“测试影响分析”方面的进展。 如果你不做.NET,你也可以很容易的设计出适合自己的一套东西。我以前的一个雇主根据我在下面分享的概念工作设计了一些东西。

缩短自动化测试的常规策略

为了实现这个构想,伴随着新的并行测试和虚拟化服务的实现,我将会回顾一 下传统的“运行子集测试”的策略,这在业界依然占据主导地位。

创建套件标签

左图:对单元、服务和功能 UI 进行分组。在单元测试中,对有意义的子组进行标记,包括一个 "express", 它对其他的子集进行抽样。

右图:这只是样例,举例购物车测试,其中有一个测试项失败,对应左边图中的shopping cart 部分

此方法适用于递归构建工具, 如 Ant、Maven、MSBuild、Rake 等等。

从历史上看, 研发团队将会放弃加速自动化测试这个方向, 而是使用标记套件 这样的子集测试方式去完成每次测试任务。随着标签测试套件的创建,每一个子 集测试都能被准确的描述。

例如“购物车的 UI 测试”。套件标记可能暗示应用 程序的业务领域, 或者是技术领域或层次结构。定义标签套件需要专家的人性化 创作设计。至少需要实现最佳分组。这就暗示着这些分组可以是不全面的,不准确的,或者不正确的,这些都是很正常的现象,毕竟这都是人为定义的。每次只进行一套测试,对应这个修改来说测试项过多,或者过少。如果过多就会浪费资源,如果过少就可能让 Bug 溜走。

有些团队可能在每次提交的时候利用CI 任务进行一些简单的标记套件测试,然后每天晚上进行全局测试。显然,这样会延迟BUG 的发现,并对持续集成的实现设置了障碍。

然而,在大多数软件开发领域都是利用标签套件测试方式进行代码测试的。

代码的预测图表和测试用例

左图:科学预测定义了 276 个测试用例

右图:对一次提交进行了自动化测试遇到两个失败。这些有的碰巧是小问题,有的是中等的,还有一些是大 的问题。这里我们利用一个树形结构也诠释这个概念(实际情况不会如此简单)

Google 传奇的内部构建系统 Blaze,多年来被复制到一些开源技术中。最值得一提是来自 Facebook 的 Buck,以及来自 Google 的 Bazel。Twitter 公司,以 及 Foursquare and Square 公司主要是使用 Pants。

在 Google 内部 Blaze 在单 一代码库中贯穿了单一的有向图。Blaze 有一种直接与产品代码相关联的测试机 制。该机制是产品代码与相关测试源关联的细粒度目录树。通过构建文件反馈代 码的依赖关系。这些构建文件可以由开发人员维护和开发,但也可以通过自动化 工具验证是否正确或不正确。随着时间的推移,这个过程不断地重复,使得有向 图更加正确和高效。

重要的是,该工具可以指出关于依赖性的冗余声明。因此,对于给定的目录/包/命名空间,开发人员可以很容易地启动一个子集测试,只需通过构建文件获 得有向图即可进行测试。这样就为开发在预集成和持续集成中节省了很多时间, 基于这个理念 CI 框架‘Forge’(后来的 TAP)就是根据每次提交,智能的进 行自动化子集测试。

在谷歌规模的继续测试中,有很多令人兴奋的统计数据。在我看来,这种东西 已经花费了谷歌几千万,但是这些年来他们赚了几十亿。或许远远大于这个收入: 工资比。

测试影响分析(TIA)

测试影响分析 (TIA) 是一种依据获得的变化结果确定一组测试子集的技术。

根据一个假设的变化进行一次测试的描述

这一想法的关键在于, 并非所有的测试都可以覆盖到产品源代码文件 (或从 该源文件生成的类)。代码覆盖率或代码检测, 这些白盒测试运行的时候,就会 收集到很多信息,这些信息 (详情如下)。从一个源代码和测试之间的关系信息 图开始, 并最终整理成整体产品代码和测试之间的关系图。

左图:一个测试用例 (很多测试用例中的一个)会检测到源代码中的一个子集

右图:一个代码模块由一个子集测试(单元测试、集成测试或功能测试)进行测试。

因此, 您将注意到, 执行测试的程式化图与上面的有向图构建技术相同。它实 际上是相似的, 因为随着时间的推移, 构建文件策略会或多或少地导致与 TIA相同的结果。

TIA 的图表可以用来描述一个参考点的变化。这就好像和研发的提交和入库的 工作一样简单。这个参考点也可以是一系列的提交。或者说今天的所有提交(每 天的定时构建),或者最后一次发布的版本。

对 TIA 的使用有个普遍的认识就是,对同一段代码会进行很多测试项。当然这 些里面很多可能是重复的,通过测试分析和代码路径分析,这些冗余的测试项也 是可能被去掉的。通常情况下,这次测试并不是你所需要的,而且进行的依赖测 试区域也是不对的,最后无可避免的需要利用重复测试,或者虚拟服务(为了集 成测试)。

根据“代码的变更”创建针对这个变化的一系列最小变更列表, 不过最理想的 做法是确定那些方法/函数改变了, 并进一步根据最小变更列表获得对应需要执 行的测试子集。现在,利用微软的研究结果,根据源码变更有一个现成的技术可 以借鉴,我会继续说明这个技术。

微软在 TIA 方面的广泛探索

微软已经投入了很长的时间在探索测试影响分析这个方向,并给出了名称和缩写概念。

从 2017 年 3 月到 7 月期间,他们发布了一系列博文:Accelerated Continuous

Testing with Test Impact Analysis - Part 1, Part 2, Part 3, and Part 4.最近 8 年内发布的一系列文章如下:

  1. Test Impact Analysis in Visual Studio 2010 (2009)
  2. Streamline Testing Process with Test Impact Analysis) (2010)
  3. Which tests should be run since a previous build? (2010)
  4. How to: Collect Data to Check Which Tests Should be Run After Code Changes(2010)
  5. Test Impact Analysis (2011)

微软的 Pratap Lakshman 详细介绍了它们的实现过程。关于他们 TIA 当前的 技术演变, Pratap Lakshman 说:

当编译构建触发后, 将重新分析受影响的测 试实例与生产代码的映射关系。在 VSTS 的编译作业中,这个将作为 VSTest测试中的一部分。 当测试执行时, 我们的 TIA 会收集每个测试方法的动态依赖性。 在很高的层次上, 我们所做的是: 当测试正在执行时, 它将涵盖各种方法--这 些方法所驻留的源文件是我们跟踪的动态依赖关系。 因此, 我们获得下面这样的映射: Testcasemethod1 <--> a.cs, b.cs. d.cs Testcasemethod2 <--> a.cs, k.cs, z.cs 等等 ... 现在, 当一个提交是关于 a.cs 的时候, 我们运行包括 a.cs 的所有Testcasemethod (s) 方法,这就是他们直接的动态依赖性关系。当然, 我们也 会关注新引入的测试 (可能会作为提交的一部分), 也会同时进行之前已有的失 败的测试。 我们目前已完成的 TIA,并没有做测试的优先级相关设置 (例如, 最常见的 是中断是最高优先级)。这个设置将来可能会有,如果对团队发展有足够的利益 我们会考虑这个方面的。 实际 TIA 映射图数据会被实时的存储在 TFS 中,就像存储在 SQLServer 数 据库中一样。当有新提交的时候,TIA 通过 TFVC / GIT 的 API 接口查看具体的 代码修改文件信息。一旦获得修改文件信息,就可以通过映射图来启动对应的测 试项。 我们在请求(PR)中和正规的 CI 工作流中都可以使用 TIA 技术,即使在研 发的预集成过程中也支持。我们希望我们的使用者可以拥抱变革,将更多的测试 放到早期的进度中。依据这个想法我们的研发可能会担心,因为在过去这就意味 着每次提交我们都要进行大量的测试工作,这样就导致一个 CI 流程时间更长。 现在希望大家响应 TIA,让 TIA 负责这些测试工作,从而获得性能的提高。

针对 TFS 和 Visual Studio 内部早期的 TIA,他说:

它只能识别受影响的测试。而且他需要研发去运行他们。 它使用代码块覆盖率作为生成测试 <--> 映射的方法。在随后的构建中, 它将与早期版本进行 IL 比较, 以查找已更改的块, 然后使用映射来标识和列出受影响的测试。请注意, 它不会为您运行它们。 上述方法使其运行速度慢 (与当前情况相比), 并且需要更多存储映射信息的方法(与当前情况相比)。 上述方法还导致比当前实现方法的安全性低 (在某些情况下, 它将忽略受影响的测试)。 它不支持 VSTS 编译流程 (只支持旧的 XAML 编译系统)

通过常规代码覆盖工具和脚本测试影响分析

当我在 HedgeServ 上班的时候,我有个相关课题就是利用现成的代码覆盖率 工具进行类似的影响分析。根据这个思路,我发布了两篇博文(相关的代码在GitHub 上):一个是针对 Maven & Java,一个是针对 Python。当时我以为我有一个新的发明。我不知道的是当时微软已经有了上面的一些理论。我所展示出来的这些技术在开发的工作流中可能是低劣的,而且在你的 CI 框架中可能需要成本。

一个简单的测试影响分析的实现需要一些前期工作:

  1. 运行单个测试,并收集代码覆盖率。
  2. 根据测试所触及的源文件, 制作出一个临时的测试源 (键) 图来标识路径/名称 (值)
  3. 更新包含主映射的源文件, 替换该测试的所有以前的项
  4. 将那些已更改的映射源文件提交给 VCS (只有指定的 CI 工具才有权这样
  5. 清除覆盖率数据 (以便每个测试的覆盖率报告不会产生混乱)
  6. 继续执行第一项#1 进行下一次测试 (最近更新的代码文件和测试)

当你完成这些所有的测试项之后,你会获得一个全面的测试和代码之间映射图。

当你后续修改代码的时候,你可以看到那些测试会对当前的改动进行测试,从 中你可以获得一些反馈数据。如果你遇到了测试失败的情况,就有可能是你当前 的修改导致的。上面两个概念对一些 python 代码试图如下工作:

  1. 提前设置 TIA 映射图
  2. 在预集成过程中使用 TIA 的映射图(在 CI 构建中可能会有或多或少的改动)

HedgeServ 的 test-base 是由常规的敏捷测试组成的, 其次是 Microsoft Excel 文件间接地调用 Python 而进行集成测试。这 1.2 万个广泛和先进的算法 测试需要进行很多小时,如果没有一些子集运行策略的话,是不可能集成到 CI基本构建里面的。

DevOps 团队的基于“减压测试流程”概念(我给这个技术最初的名字)实践 的构建流程,现在最快的构建只需要 10 分钟。这是个很大的进步。开发人员和 测试工程师可以在预集成阶段使用这个方法,而且 CI 构建流程里面也可以实施 这个方法。HedgeServ 软件的开发总经理 Kevin LOO,曾经告诉我说“更快捷 的测试,能加快研发进度,这样可以增加研发的自信心”。

由于TIA利用常见的代码覆盖率工具,就必须一次运行一个测试, 这个是必然 的前期成本。所以就需要在代码控制中添加分析映射关系图,并且需要增量更新。 因此, 就必须是文本的,并可控制的,只有这样才能更加简洁和具有意义。将映 射图嵌入到代码管理中也有利于 CI 构建流程的和单个开发人员在预集成之前进 行较少的测试(和代码审批)。

利用代码覆盖率工具进行的 TIA 设计是有局限性的:为了计算出一个精确的 映射图,同一时间内每次只能跑一个测试项。为了利用这个映射数据,我们需要 运行一些 git 命令,例如 git status,git show 以及 hash 命令,然后我们才能得 到代码的变更状态,例如“修改,添加,删除等”。而且这些状态是映射图中的 关键值,能够触发一系列测试事件进行工作。CI 构建中只有数据收集 “同一时 间只能运行一个测试事件”有局限性,这就是为什么你会觉得它连续运行的原因。

目前的测试技术可能和你需要分析的代码是不兼容的,这是可以理解的。以HedgeServ 的例子来说,他们的算法测试是利用微软 Excel 文件部署到代码控 制流程里面(或者 Bas 来帮忙)。如果类似于 SmartBear 的测试,或者惠普的 单元函数测试(UFT-之前的 QTP),或者 Selenium 都是可行的。这个里面唯 一的要求就是测试需要在同一时间用脚本运行(当你构建 TIA 映射图的时)。你 也可以利用 CI 基础构建流程去不断的更新你的初始映射图

然后, 您将决定存储映射数据的位置。您可以选择文件共享、文档存储或关系 模式。我选择了 (并建议) 在目录中保存文本文件,和检测代码的仓库/分支定义 保持一致。这至少可以分支管控 (无所谓您的分支模型), 并且可以根据代码提交 轨迹反应出映射图的变更。

最近我正在为一个使用 KDB 和 Q 进行系统开发的客户工作,指导他们如何减 少他们的测试时间。对于 KDB 和 Q 而言,目前是没有对应的代码覆盖率技术的, 这个问题先说到这里。

VectorCAST/QA – 应用

Vector 软件公司做了一个产品叫“VectorCASE/ QA 是一个一站式商店的应用 程序,利用代码覆盖率的方式减少关联性测试(或者更多)。他们的技术大多是 卖给汽车(及相关)的行业,嵌入到 C、C++和 Ada 代码中。这种操作模式也 早过我的研究实验。我要提升一下我的搜索技巧!

VisualStudio 中的插件 NCrunch

. NET 团队在经过几年的发展之后于 2011 年启动了 NCrunch。在 Visual studio 中这个复杂的插件可以预测到那些改动最可能引起中断,从而优化测试优 先级顺序。2014 年又新增了一些功能,可以根据代码更改进行对应的子集测试。 同年NCrunch普遍运行到CI系统里面。具体的说, 它能够在 VisualStudioUI 之 外协调执行 MsBuild 构建, 并行操作,节省时间,这都是大家乐见的。原始映射 数据不存储在源代码中管理中, 因为它是二进制的, 但可以在开发人员和 CI 基 础构建实现网络共享。 NCrunch 是商业的, 对于每个开发商 (和每个测试工程 师)需要支付合理的许可证费。2017 年 NCrunch 的创造者 Remco Mulder 同意 提供免费的节点, 通过 Docker 扩展他们的 CI,当然不需要支付两次费用。

TIA 支持 IDEs

微软在 Visual Studio 中也集成了强大的动态单元测试(4)功能,如果启用, 即使在编辑代码时,也会自动触发相关联的单元测试。虽然与 TIA 有关,但这也 值得单独分析。

上个月,我想应该针对 JetBrains 提出一个功能需要 raise a feature request for JetBrains 等效于 IDEs 里面的 TIA 函数功能。在需求分析过程中我想到了 2010年针对 JetBrains 有过相同的需求 another one from 2010 on the same topic。 部分功能函数已经实现了,不过当我试着去运行他们的时候却没有成功。

DevOps高翻院 翻译官

张鹏飞

原文地址:https://martinfowler.com/articles/rise-test-impact-analysis.html

END

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DevOps时代 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
持续集成
CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档