测试影响分析的兴起
测试影响分析 (TIA) 是一种现代方法,可以加速构建的测试自动化阶段。它通过分析源代码的调用图来确定在更改生产代码后应运行哪些测试。微软在这方面做了大量工作,但开发团队也可以以相当低的成本实现一些有用的东西。
2017 年 8 月 22 日
现代软件开发的一个诅咒是拥有“太多”测试,以至于在签入之前需要运行所有测试。当这种情况发生时,开发人员会使用一种代价高昂的应对策略,即不在本地开发工作站上运行任何测试。相反,他们依赖于稍后在集成服务器上运行的测试。而且,即使是那些测试也经常处于失修状态,这是不可避免的,因为当 向右移 成为开发团队的常态时。
当然,您测试的所有内容都应该在 持续集成 (CI) 基础设施中立即进行测试,即 预集成 和 后集成。即使是功能最强大的开发团队也可能会遇到由于提交实时落地而产生的时间问题导致的故障。这些团队也可能有人有时想在商定的集成流程上“节省开支”,而不运行测试。幸运的是,CI 服务器和一系列合理的构建步骤是您快速捕捉这些时刻的方法。
存在各种技术可以加快测试执行速度,包括在多台机器上并行运行测试以及对缓慢的远程服务使用 测试替身。但这篇文章将重点关注减少要运行的测试数量,方法是识别最有可能识别新添加的错误的测试。使用 测试金字塔 结构,我们更频繁地运行单元测试,因为它们通常运行速度更快,更不容易出错,并提供更具体的反馈。特别是,我们构建了一套应该作为 CI 部分运行的测试:预集成和后集成。然后,我们创建一个部署管道来稍后运行速度较慢的测试。
相同的问题重新陈述:如果测试可以无限快地运行,我们会一直运行所有测试,但事实并非如此,因此我们需要在运行测试时平衡成本与价值。
在本文中,我详细介绍了一个新兴的测试相关计算机科学领域,微软在该领域处于领先地位,拥有长期测试自动化套件的公司应该注意这个领域。如果您身处 .NET 生态系统,您可能会立即从微软在“测试影响分析”方面的进步中受益。如果您没有使用 .NET,您必须能够以相当低的成本自行设计一些东西。我以前的一位雇主根据我下面分享的概念验证工作自行设计了一些东西。
缩短测试自动化的传统策略
为了完整起见,我将回顾传统的“运行测试子集”策略,这些策略在行业中仍然占主导地位。好吧,有了并行测试执行和服务虚拟化的最新现实。
套件和标签的创建
单元、服务和功能 UI 的主要分组。在单元测试中,对有意义的子分组进行标记,包括一个“快速”标记,它对其他标记进行子集采样。
在运行“购物车”测试后,除了一个测试外,所有测试都通过了。这里。
这种方法适用于递归构建技术,例如 Ant、Maven、MSBuild、Rake 等。
从历史上看,团队会放弃让他们的测试无限快地运行,而是使用套件或标签来定位任何时候的测试子集。通过创建套件和标签,可以对测试子集进行口头描述。例如,“购物车的 UI 测试”。标签或套件可以暗示应用程序的业务领域,或者暗示技术或分层分组。定义标签和套件需要专家的人工设计创造力。至少为了推动最佳分组。这意味着它们也可能分组不足、不精确和分组错误,这很常见,即使对人类来说很难确定。同时执行的测试太少和太多,对于只运行一个套件来说是一个很大的可能性——浪费了计算资源和时间,而且还存在让错误溜过去的风险。团队可能会选择让 CI 作业使用每个提交的较小子集,然后也让夜间构建作业运行所有测试。显然,这会延迟坏消息,并违背了 持续集成 的目标。
然而,套件和标签是大多数软件开发世界组织其测试代码库的方式。
源代码与测试的预先计算图
276 个测试及其名义上的“大小”指定。
为给定提交执行的测试,有两个失败的结果。碰巧的是,其中一些结果很小,一些结果中等,一些结果很大。我只描绘了一棵树/分形,因为它有助于解释概念(它并不完全是这样)。
谷歌传奇的内部构建系统 Blaze 这些年来已被复制到一些开源技术中。最值得注意的是 Facebook 的 Buck 和谷歌的 Bazel。Twitter、Foursquare 和 Square 的 Pants。谷歌内部的 Blaze 在整个单一存储库中导航单个有向图。Blaze 具有将测试直接与生产代码关联的机制。该机制是生产源代码和相关测试源代码的细粒度目录树。它通过 BUILD 文件进行显式依赖声明,这些文件也被签入。这些 BUILD 文件可以由开发人员维护和演变,但也可以通过自动化工具验证其正确性或错误性。随着时间的推移,这个过程不断重复,这在很大程度上使有向图变得正确且高效。
重要的是,该工具可以指出关于依赖关系的冗余声明。因此,对于给定的目录/包/命名空间,开发人员可以非常轻松地启动测试子集——但只有通过 BUILD 文件中的有向图才能实现的测试。最终的省时方法,无论是对于开发人员的 预集成 还是集成基础设施,都是基于这种内置智能的扩展 CI 基础设施“Forge”(后来的 TAP),它可以自动对每个提交运行的测试进行子集划分。
在 驯服谷歌规模的持续测试 中,有很多令人惊叹的统计数据。在我看来,这些东西让谷歌花费了数千万美元,但多年来也为他们带来了数十亿美元的收益。也许远远超过了收益:工资比率。
测试影响分析
测试影响分析 (TIA) 是一种技术,可以帮助确定给定一组更改的测试子集。
类似的描述,用于为假设的更改运行测试。
这个想法的关键在于,并非所有测试都执行每个生产源文件(或从该源文件生成的类)。代码覆盖率或检测,在测试运行时,是获取该智能的机制(详情见下文)。这种智能最终会变成生产源代码和会执行它们的测试的映射,但最初会变成测试会执行哪些生产源代码的映射。
一个测试(来自多个测试)执行生产源代码的子集。
一个生产源代码由测试子集执行(无论是单元测试、集成测试还是功能测试)。
因此,您会注意到,执行测试的风格化图表与上面有向图构建技术的图表相同。它实际上是相同的,因为随着时间的推移,BUILD 文件的管理会导致与 TIA 几乎相同的结果。
TIA 映射只能真正用于更改与参考点的比较。这可以像开发人员要提交或已提交的工作一样简单。它也可以是一堆提交。比如今天提交的所有内容(夜间构建),或者自上次发布以来的所有内容。
使用 TIA 方法的一个认识是,您有太多测试覆盖了生产代码的相同部分。如果这些测试是完全重复的,那么在分析测试和它执行的生产代码路径后删除测试是一种可能性。但通常情况并非如此,而如何将测试重点放在您想要测试的内容上,而不是完全放在代码中的传递依赖关系上,这是一个不同的关注领域,它不可避免地依赖于使用 测试替身 的既定实践,以及最近的服务虚拟化(用于集成测试)。
创建已更改内容列表的最低级别是“已更改的生产源代码”,但理想情况是确定已更改的方法/函数,并进一步子集化到仅执行这些方法/函数的测试。不过,现在微软有一项现成的技术可以按源文件级别工作,以及一项可重用技术(由我提供)。继续阅读。
微软在 TIA 方面的广泛工作
微软在将测试影响分析的想法投入生产方面付出了最长久的努力,并为这个概念命名了它的名称及其缩写。
他们目前有一系列博客文章,涵盖了 2017 年 3 月到 8 月,到目前为止:使用测试影响分析加速持续测试 - 第 1 部分,第 2 部分,第 3 部分,以及 第 4 部分。
他们关于此的较早文章可以追溯到八年前
- Visual Studio 2010 中的测试影响分析 (2009)
- 使用测试影响分析简化测试流程) (2010)
- 自上次构建以来应运行哪些测试? (2010)
- 如何:收集数据以检查代码更改后应运行哪些测试 (2010)
- 测试影响分析 (2011)
微软的 Pratap Lakshman 详细介绍了他们实现的演变。关于他们 TIA 技术的当前演变,Pratap 说:[1]
当触发构建时,会重新计算受影响测试与生产代码的映射。执行此操作的作业作为 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 打开提交并查看更改将要进入的文件。一旦知道文件,TIA 就会参考映射以了解要运行哪些测试。
当然,在拉取请求 (PR) 和常规 CI 工作流程中,以及在开发人员工作站上的 预集成 中,都支持使用这种 TIA 技术。
我们希望我们的用户能够拥抱 左移,并将尽可能多的测试移到管道中的更早阶段。在过去,我们看到一些客户对此有些担心,因为这意味着在每次提交时都要运行更多测试,从而使 CI 构建花费更长时间。有了 TIA,我们希望让用户 左移,并让 TIA 负责只运行相关的测试,从而解决性能问题。
关于 TIA 在 TFS 和 Visual Studio 中的头几年,他说
当时的 TIA 技术在很多方面都不同
- 它只会识别受影响的测试。用户需要显式地运行它们。
- 它使用块级代码覆盖率作为生成测试 <--> 映射的方法。在随后的构建中,它将对早期构建进行 IL 差异比较,以找出发生更改的块,然后使用映射来识别和列出受影响的测试。请注意,它不会为您运行它们。
- 上述方法使其速度较慢(与当前实现相比),并且需要更多存储空间来存储映射信息(与当前实现相比)。
- 上述方法还导致其安全性低于当前实现(在某些情况下会错过识别受影响的测试)。
- 它不支持 VSTS 构建工作流程(它只支持旧的 XAML 构建系统)。
通过传统代码覆盖工具和脚本进行测试影响分析
当我还在 HedgeServ 工作时,我有一个想法,就是将现代的现成代码覆盖工具整合到相同的冲击分析中。从这个想法出发,我创建了两个概念验证博客条目(在 Github 上有相关代码):一个用于 Maven & Java[2],另一个用于 Python[3]。当然,就像一个 eejit 一样,我认为我有一个新颖的发明,但我当时并不知道在这个领域已经有很多先例(微软就是其中之一)。我展示的技术在您的工具链中开发成本低廉,即使它在您的 CI 基础设施中运行可能会有成本。
测试冲击分析理念的简单实现需要您事先进行一项活动
- 运行单个测试并收集其代码覆盖率
- 从测试触及的生产源文件中,创建一个临时映射,将生产源文件(键)映射到测试路径/名称(值)。
- 更新包含主映射的源文件,替换该测试的所有先前条目。
- 将这些更改后的映射源文件提交到 VCS(只有相关的 CI 作业应该有权限执行此操作)。
- 清除覆盖率数据(以免将每个测试的覆盖率报告纠缠在一起)。
- 返回到步骤 1,进行下一个测试(最近更改的源文件/测试优先?)。
在逐个运行所有测试后,您将获得一个全面的映射,将生产代码连接到覆盖它们的测试。
然后,当您稍后对某些生产代码进行更改时,您可以找出哪些测试执行了该代码,因此在运行时可能会有信息量。产生的任何测试失败都证明是更改所导致的唯一可能发生的测试失败。上面提到的两个概念验证包含少量 Python 代码,试图
- 提前计算 TIA 映射
- 在 预集成 情况下使用 TIA 映射(稍作修改,也可以在 CI 作业中使用)。
HedgeServ 的测试库由常规的快速单元测试组成,然后是集成测试,这些测试是 Microsoft Excel 电子表格,这些电子表格间接调用 Python。共有 12,000 个。这些测试是数小时的广泛而高级的算法测试,如果没有一些“减少运行次数”的策略,在 CI 基础设施中每进行一次集成就进行一次测试是不可能的。他们的 DevOps 团队将概念验证操作化为“测试缩减器”(我最初给这个技术起的名字),最快的排列现在只需要十分钟。这是一个巨大的进步。开发人员和测试工程师可以在 预集成 时运行它们,CI 基础设施也可以这样做。HedgeServ 的软件开发总经理 Kevin Loo 告诉我,“开发人员依赖于更快的测试运行,由于信心的增强,开发速度也加快了”。
由于使用了通用的代码覆盖工具,因此 TIA 方面必须一次运行一个测试,这会产生前期成本。因此,分析产生的映射被检入源代码控制并逐步更新。因此,它必须是文本形式且有序的,以便差异可以简洁且有意义。将映射检入源代码控制也有利于 CI 基础设施和希望在集成(和代码审查)之前运行更少测试的个人开发人员。
这种 TIA 设计由于代码覆盖工具的性质而存在局限性:为了计算准确的冲击图,一次只能运行一个测试。为了使用映射数据,需要运行“git status”(或 git show >hash>),然后解析输出以找到“更改/添加/删除”的生产代码源文件。这些是冲击映射的键,它们会生成要运行的测试列表。只有数据收集 CI 作业存在“一次运行一个测试”的限制,这就是为什么您或多或少地认为它一直在运行的原因。
正如您所见,测试技术可能与您为生产代码选择的语言完全不同。在 HedgeServ 的情况下,他们的算法测试是在源代码控制下的 Microsoft Excel 文件中进行的(即使业务分析师也参与其中)。如果这可能,那么 SmartBear 的 TestComplete、HP 的统一功能测试 (UFT - 前身为 QTP) 以及 Selenium 也是如此。唯一的要求是测试可以被脚本化,以便一次运行一个测试(在您构建 TIA 映射时)。您还必须承诺在初始创建后定期更新映射 - 使用您的 CI 基础设施。
然后,您需要决定将映射数据存储在何处。您可以选择文件共享、文档存储或关系模式。我选择(并推荐)将文本文件存储在与生产源代码相同的存储库/分支中的目录中。这样至少可以让分支工作(无论您的分支模型是什么)并可能具有不同的冲击映射,反映代码的不同性质。
最近,我为一个客户查看了一个使用 KDB 和 Q 的项目,并试图就如何缩短测试时间向他们提供建议。这些语言没有代码覆盖技术,所以谈话就到此结束了。
VectorCAST/QA - 应用
Vector Software 推出了一款名为 VectorCAST/QA 的产品,它是一个一站式应用程序,利用代码覆盖率以相同的方式运行更少的受影响测试(以及更多)。他们的技术主要销售给嵌入 C、C++ 和 Ada 软件的汽车(及相关)行业。VectorCAST 以这种运行模式工作也早于我的厨房水槽实验。我需要改进我的谷歌搜索技能!
VisualStudio 的 NCrunch
NCrunch 是面向 .NET 团队的工具,它在经过两年的开发后于 2011 年推出。它是一个用于 Visual Studio 的复杂插件,可以根据预测哪些测试最有可能因更改而中断的算法来优化测试的运行顺序。2014 年,添加了额外的功能,使其能够将测试子集化,只包含受更改影响的测试。同样在 2014 年,NCrunch 变得与 CI 使用情况普遍兼容。具体来说,它能够在 VisualStudio UI 之外编排 MsBuild 的执行,并具有您期望的相同时间节省。原始冲击映射数据没有存储在源代码控制中,因为它以二进制形式存在,但可以在网络共享中开发人员和 CI 基础设施之间共享。NCrunch 是商业软件,但价格合理,按开发人员(和测试工程师)收费。CI 节点是免费的,NCrunch 的创建者 Remco Mulder 同意,没有人应该为同一件事支付两次费用,或者因为在 2017 年通过 Docker 等方式扩展了 CI 基础设施而受到惩罚。
IDE 中的 TIA 支持
Microsoft 在 Visual Studio 中还提供了一个强大的实时单元测试[4] 功能,如果启用,它会在您编辑代码时自动运行受影响的单元测试。虽然与 TIA 相关,但这可能值得单独分析。
上个月,我想为 JetBrains 提出一个功能请求,让他们为他们的 IDE 创建等效的 TIA 功能。在对我的票证进行分类时,JetBrains 将其与 2010 年关于同一主题的另一个票证 联系起来,在那个票证中,有人建议这些功能中的一些 已经实现。但我尝试时却无法使其正常工作 ☹️
定义
预集成和后集成
预集成活动是指开发人员在其工作站上进行的活动,这些活动可能包括本地(希望是短暂的)功能分支、小提交(这些提交可能被压缩成一个提交,也可能不被压缩,以及在宣布相关故事卡片“完成”之前进行的编辑/构建循环。它肯定是在提交/提交被传递到代码审查等之前进行的。
后集成是指该工作(一个或多个提交)已完成代码审查并返回到主干/master/主线。之后不久,所有团队成员都将能够将其拉取到他们的工作站,并且可能应该这样做。
左移和右移
左移是指将软件开发价值流的一部分步骤提前到时间线上。将手动测试替换为测试自动化就是一个例子。另一个例子是在产品负责人将缺陷输入到积压工作(故事跟踪器)之前,在产品负责人脑海中发现缺陷。在这种情况下,缺陷是一个产品想法,它将在跟踪器中成为一个功能请求 - 最终会被判断为指定错误 - 而不是一个错误。这可能是无意的,但如果您实施了一个新的流程来做到这一点,那么它将成为左移议程的一部分。 Barry Boehm 的“变更成本曲线”谈到了更大的主题 - 错误越早发现,修复成本越低,而在生产中发现时,修复成本最高。碰巧的是,“左移”是一个次要的行业原因。企业正在使用它来描述一种替代方法,解释对更便宜和更快的追求。与持续集成(尤其是敏捷、CD 等)的目标相同。
右移是指您进行非敏捷的事情,例如将单元测试执行移到“夜间”构建(或更不频繁的构建)中,而不是在每次集成 CI 构建中使它们更快。有时,您已经完成了一系列左移活动,这些活动伴随着一些风险,只有通过额外的右移步骤才能缓解这些风险。
该领域的早期工作
Google-Testar(2006 年)
Mikhail "Misha" Dmitriev 在 2006 年加入 Google 时创建了 Testar。
Misha 的目标:不要运行所有测试,同时声称“我们可以用经验证明我们不必这样做”。
Testar 使用字节码插桩来记录每个测试的代码覆盖率——也就是说,每个测试运行了哪些应用程序方法。这些信息,以及类和方法的校验和,被保存到测试数据库 (TDB) 中。在后续调用中,Testar 会找出开发人员更改了哪些类和方法,然后只重新运行覆盖更新代码的那些测试。假设其他测试在之前通过了,它们会再次通过,因为它们运行的代码没有改变。当然,如果任何测试之前没有通过,或者刚刚被添加,Testar 会无条件地运行它。
Misha 报告说,由于没有运行“不受影响”的测试,平均节省了 60% 到 70% 的时间。但是,这项技术并非没有问题。首先,节省的时间不一致:例如,如果开发人员反复更改一个被大多数测试使用的函数,那么节省的时间就会很小。其次,如果测试结果不仅取决于代码,还取决于一些外部输入,例如资源文件,用户需要明确地将所有这些文件指定给 Testar。该工具无法自动确定哪些测试依赖于给定的资源文件,只能重新运行所有测试或用户明确指定的那些测试。
Misha 在此处的反思:[5]
当时,现成的字节码插桩库还不够成熟,或者缺乏灵活性。我经常发现,除非某个库是顶级的,否则从一开始就编写更多自己的代码更有意义,这样以后就能有更大的自由度。
Misha 关于他在 Google 和其他公司的经验
我最终得出结论,如果一家公司运行各种各样的测试,并且拥有足够的硬件资源,那么像 Testar 这样的技术可能不是最佳选择。在这种情况下,以高度并行的方式运行所有测试更加可靠。但是,Testar 所做的细粒度选择性测试执行仍然可以在某些特定情况下发挥作用。例如,当单个测试需要非常长的时间,并且无法通过并行化或其他技术来加速时,或者当硬件资源有限,但测试的资源文件和其他非代码输入没有问题时,等等。
在我看来,如果有人想让 Testar 重获生机,它可以被重新振兴。此外,Testar 是我找到的第一个进行 TIA 的技术,但它是基于一篇在会议上发表的论文,该论文讨论了这些概念。Misha 说他今天找不到那篇论文。
ProTest:脆弱的测试应该尽早失败
在 2007 年,一些 Thoughtworks 同事 Kent Spillner、Dennis Byrne、Naresh Jain 和其他人开源了 Protest,该工具试图首先运行最有可能失败的测试。最有可能的组合是历史上的故障统计数据,以及生产或测试源代码当前是否正在更改。最近更改的生产源代码文件会影响测试,这些测试将成为优先考虑的候选者。更改的测试也将成为候选者。历史上最脆弱的测试和最近更改的测试的交集将是自定义 JUnit 测试运行器首先执行的测试。相关的构建步骤总共需要相同的时间,但测试失败的消息可以更快地发布。这是因为 CI 技术不会等到构建步骤结束才发布失败消息,因为它们会监听每个测试的日志事件,或者抓取日志输出。对于集成到 IDE(Intellij 和 Eclipse)中的运行器也是如此。
Naresh 回忆
我们构建了一个 AST,然后使用访问者模式遍历代码并收集有趣的统计数据。就步骤而言,ProTest 做了以下事情
- 在启动测试阶段,ProTest 处理测试和生产类的字节码,以构建生产类与测试的映射
- 它根据源文件的时间戳计算工作副本中的更改
- 从这些更改中,它计算出必须运行的最小测试集,并首先运行它们
- 测试报告按正常方式发布,并为该集合发布相应的通过/失败结果
Dennis 添加
Kent 为任何你想要使用的可插拔算法编写了一个扩展点,该算法基于 孔多塞投票策略(每个投票者必须对所有候选人进行排名)。我编写了一堆引导算法。其中一个使用 ASM 来构建依赖关系图,然后根据测试与更改内容的接近程度对测试进行排序。不过我们从未达到 1.0 版本 🤔
Kent 这样看待 ProTest
该映射不会在调用之间保留,因为它不需要保留,哪些测试应该运行的计算是一致的,而且非常快。我见过的最接近 ProTest 的东西是 Kent Beck 的 JUnit Max,但这可能是 Dennis 提出 ProTest 的想法几年之后。我希望我们能做更多的事情来完成 ProTest。直到今天,我经常发现自己仍然处于真正需要类似东西的情况。我知道 Naresh 后来招募了一些人继续开发它,但那项工作也停滞了。也许有一天,其他人会接过接力棒,继续前进。这就是开源的魅力,对吧?
JTestMe:“Just Test Me”
同样在 2007 年,一些其他 Thoughtworks 同事 Josh Graham 和 Gianny Damour 合作开发了一项名为 JTestMe 的开源技术,该技术使用 AOP 来构建生产类与运行它们的测试的存储库。它与 ProTest 非常相似,因为它也希望优先考虑最有可能失败的测试。
Josh 回忆
使用运行时调用分析背后的原因是,尽管静态分析对 Java 有用,但它并不能揭示具有反射功能的平台上的所有内容,以及鼓励使用其他语言的平台,包括那些静态分析不太直接的语言(例如,当时的 JRuby,以及现在的 Clojure)。
概念验证很简单,也很快。它在运行测试套件期间在所有 JUnit 测试方法(即测试用例)上创建了一个切入点。该切入点在调用任何非测试类的非私有方法时发出通知。然后,该通知会记录该类的源文件名以及当时正在执行的测试。
有了这个源代码文件名到测试用例的映射,只要源代码文件发生更改,就会知道需要运行哪些测试用例。我称之为“动态定义的 冒烟测试”。在 CI 服务器上,会提取修订信息并用于查询映射,以确定哪些测试用例可以首先运行。在开发人员的本地机器上,基于 inotify 的工具会在源代码文件发生更改时发出通知,并且会以一个辅助进程运行触及该类的测试用例。在 IDE 中,我使用优秀的 Infinitest,并使用一个自定义列表(不断更新,通过查询 JTestMe)。映射本身是一个简单的 Java 对象序列化到文件。它可以提交到源代码控制中,因为它会继续保存 CI 在构建之间重新执行它,这在基于代理的构建中可能是一个很大的问题。
我选择了加载时编织,这样测试套件就可以在有或没有插桩的情况下运行(以防 AOP 工具以某种方式创建了错误的测试结果)。
这种方法的明显缺点是,当创建新的测试用例时(通常在 TDD 团队中),它不会被包含为冒烟测试候选者,直到它被插桩,因此在开发管道中的几个地方有一些简单但繁琐的命令行更改。更符合这种方法的标准工具会吸引更多团队来享受其好处。唉,在被货物崇拜和追逐流行语淹没的团队中,精确的规范和验证仍然是一个非常低估的资产。
顺便说一句,构建“Clover”(不久后被 Atlassian 收购)的团队做了类似于 ProTest 静态分析方法的事情。
Wallaby.js:JavaScript 的连续测试,边写边测
Wallaby.js 是一款商业化的 JavaScript 集成连续测试工具,它会在你键入时立即运行测试,并在你的 IDE/编辑器中显示执行结果(包括代码覆盖率、错误和控制台消息)。它还提供一些实时更新的漂亮测试和代码覆盖率报告。为了尽可能快地运行测试,它结合了静态/动态分析和许多启发式方法,以及测试并行化。对于制作 Wallaby 的 Artem Govorov 来说,复杂之处在于测试框架和转译语言都需要分析和支持,以确保一切兼容。Wallaby 也是专为 IDE/编辑器设计的,它优先考虑正在实际处理的代码。它不知道 Git 或任何控制底层源文件的 VCS,因此不会使用 TIA 对测试进行子集划分。也就是说,没有人曾经构建过一个纯 JavaScript 测试套件,其中“运行所有测试”不够快。
脚注
1: 这些摘录来自我和 Pratap 之间的电子邮件交流。
2: 之前的博客文章:通过仅运行受影响的测试来减少测试时间 - 适用于 Maven 和 Java。
3: 之前的博客文章:通过仅运行受影响的测试来减少测试时间 - Python 版本。
4: 文章:使用 Visual Studio 2017 进行实时单元测试,位于 Microsoft.com 上。
5: 这些评论,以及本附录中的其他贡献,来自与各个贡献者的电子邮件。
重大修订
2017 年 8 月 22 日:更新以包含 NCrunch 和 Wallaby.js
2017 年 8 月 7 日:首次发布