测试自动化的 10 个最佳实践
Posted ENG八戒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试自动化的 10 个最佳实践相关的知识,希望对你有一定的参考价值。
*以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/qavI7z8IAy8qaiQvuQgURQ
虽然大家都知道坚果是非常健康和有营养的,但是,当你尝试吃它的时候,我猜测过程都不会很顺利。
现实就是那么相似,我们都知道测试自动化对软件开发有好处(就像坚果对我们的身体一样!),很遗憾很多公司在不考虑细微差别的情况下就赶着上线测试自动化。如果您不遵循一些规则,您可能会弄巧反拙。
为了避免这种情况,我尝试收集了 10 个测试自动化的最佳实践建议以供大家参考。
计划先行
无规矩不成方圆,做测试也是如此。自动化测试需要策略,策略需要详细的规划。计划在开发阶段将需要哪些测试和测试次数,目的是修复遇到的bug,还有发生错误的根本原因。开发完成之后,任然需要计划回顾,也就是常说的复盘会议,目的是减少重复错误的发生。
必工欲善其事必先利其器
自动化测试的本意是利用工具帮助测试工程师脱离繁杂而重复的细节,并加快测试过程。说到测试自动化的工具,包含了编写测试脚本、运行测试过程、汇总报告、分析问题、跟踪问题、修复bug和方便内部团队沟通的工具。
关于开发人员使用的测试框架,我曾经在其它的推文里介绍过一款 Google 开源的 C++ 测试框架,有兴趣可以点击下方链接了解一下。
《C++ 测试框架 GoogleTest 初学者入门篇 丙》
可见需要的工具名目众多,而且分阶段配合,也非常需要集成到统一的平台并便于成员理解各个阶段的作用和相互协调。
那么有哪些平台已经在做这些事情呢?
比如,Katalon、LambdaTest、Perfecto、Zebrunner等。
在项目早期就开始
团队首要任务其实是为了获取成果和企业赚取收益,团队产出的项目成果越早推向市场,越有机会为团队创造效益,毕竟剩下来的都是成本,软件行业最大的成本就在于劳动力的开销了。如果项目bug发现得越早并且修复完整,那么成果就容易得到主管层的认可,产品上市的门槛算是迈过了。
bug发现越早,留给工程师修复的时间也就越多,严重的问题更适合在项目早期就发现,后续跟进的同事也能对此类问题了解更全面。否则,等到工程代码堆积如屎山,待到何时休?唯有项目难产了。
合理利用虚拟环境和真实应用环境
软件的运行在发布到用户手里之前,可以在虚拟的环境里测试,虽然仅可以对功能测试,但是费用是非常廉价的,任何规模的企业都可以使用。
如果还需要测试产品的性能,获取实时数据,比如传感器、部件、网络信号强弱、电量等,必须要使用到真实的应用环境才可以达到目标。真实的应用环境往往需要购买特定的设备配合测试,这些设备还要考虑定期维护保养,所以成本也是一个很重要的因素了。
为了平衡测试目标和成本因素,虚拟环境和真实应用环境测试需要合理安排,做到平衡。
手动自动相互配合
凡是求个度,适度就是好,包括测试自动化。现时情况下,很多因素的作用,测试只能手动执行,所以将它们自动化是没有意义的,否则就是画蛇添足了。
首先,脚本无法模仿人类的所有行为和反应。其次,如果计划的测试只需只执行一次,那么没有必要为此写个自动化脚本,等写完脚本,花都谢了。
那么哪些测试非常适合实施自动化呢?下面做了个列表:
需要实施自动化的测试场景: |
---|
大量重复动作 |
操作大量数据 |
需要注意力比较集中的操作 |
需要兼顾各种运行平台的功能,比如不同操作系统、浏览器、硬件等 |
比较常用的功能 |
回归测试
在添加新功能后需要执行一轮测试用以检查功能是否正常工作,这样的测试就叫回归测试。
回归测试是需要重复执行的,所以自动化地执行并一遍又一遍地运行就显得很必要了。一般建议在回归测试套件种添加冒烟测试、完整性测试和测试用例,方便在测试周期中发现更多的bug。
端到端(E2E)测试
端到端 (E2E) 测试是从终端用户的角度出发,模拟他们在实际环境下使用应用程序的交互过程,可以确保应用程序按照产品要求运行和正确处理各种用户任务。E2E 测试自动化了用户的关键操作,使得软件的错误可以被快速发现和立刻修复,所以对软件发布时间的加快有很好的推动作用。
切忌独揽所有环节
试想下,你的团队里如果创建脚本、运行测试和维护它们的都是一个人,那么你的团队工作速度必然难以快速响应,改代码的速度也会受到影响,更可怕的是如果这人请病假或者离职了会导致所有的测试流程完全暂停,风险是很高的。所以提倡测试流程共享所有权。
如果每个成员都充分了解项目的测试阶段,他们或许可以为流程做出更多贡献。测试工程师如果都能共享测试脚本,那么其中优秀的知识和技能也能被传播到其他成员。还有,共享测试会使到测试过程更加透明。
预期和结果对比,效率最大化
上面提到测试需要计划,比如目标是什么类型的测试,预估编写测试脚本的工时,运行测试时长,重新发布测试版本软件要多久,再次启动测试过程,测试过程的覆盖率是多少等等,最终会有个总体的时间预估。
在测试工作结束后,对比一下预期的计划和实际的花费,为下一阶段的工作做好调整,目标是实现效率的最大化。
保持更新
测试的目的是为了筛选出问题,如果过时的测试导致假阳性或者假阴性的结果,会增加工程师分析和修复错误的时间,减低工作效率,最终还可能误导工程师发布带病的版本软件。虽然通过自动化测试提高了测试的覆盖率,但这是以测试结果准确为前提的。
所以在回归测试中,要及时删除过时的测试例程,更新对应的功能测试。
单元测试最佳实践:如何最大程度地利用测试自动化
单元测试是一种众所周知的做法,但是还有很多改进的空间!在这篇文章中,最有效的单元测试最佳实践,包括一路最大化自动化工具的方法。我们还将讨论代码覆盖率、模拟依赖关系和整体测试策略。
什么是单元测试?
单元测试是测试应用程序的单个单元或组件的一种做法,目的是验证每个单元或组件是否正常工作。通常,一个单元应该只占应用程序的一小部分——在Java中,它通常是单个类。请注意,我并不是在这里严格定义“单元”,而是由开发人员来决定每个测试的测试代码范围。
人们有时将“单元测试”与“集成测试”或“端到端测试”相对比。区别在于,通常通过进行单元测试来验证单个可测试单元的行为,而集成测试则是在一起验证多个组件或整个应用程序的行为。就像我说过的那样,对“单元”的定义并没有严格定义,具体取决于每个测试的范围。
为什么要进行单元测试?
单元测试是一种行之有效的技术,可确保软件质量,并带来很多好处。这是(多个)进行单元测试的重要原因:
1)单元测试可以验证您的每款软件不仅可以在今天正常运行,而且可以在将来继续运行,为将来的开发奠定了坚实的基础。
2)单元测试可以在生产过程的早期阶段识别出缺陷,从而降低了在开发周期的后期阶段修复缺陷的成本。
3)单元测试的代码通常更安全地重构,因为可以快速重新运行测试以验证行为没有改变。
4)编写单元测试迫使开发人员考虑设计生产代码以使其适合于单元测试的程度,并使开发人员从不同的角度看待他们的代码,鼓励他们在实现过程中考虑极端情况和错误情况。
5)在代码审查过程中包含单元测试可以揭示修改后的代码或新代码应如何工作。另外,审阅者可以确认测试是否良好。
不幸的是,过于频繁的开发人员要么根本不编写单元测试,要么没有编写足够的测试,要么不维护它们。我了解——单元测试有时编写起来很棘手,或者维护起来很耗时。有时会有一个截止日期,感觉就像编写测试会让我们错过那个截止日期。但是没有编写足够的单元测试或没有编写好的单元测试是一个容易陷入的陷阱。
因此,请考虑以下有关如何编写干净、可维护的自动化测试的最佳实践建议,这些建议可以用最少的时间和精力为您提供单元测试的所有好处。
单元测试最佳实践
让我们看一些构建,运行和维护单元测试以达到最佳结果的最佳实践。
· 单元测试应该值得信赖
如果代码损坏并且只有代码损坏,则测试必须失败。否则,我们将无法相信测试结果在告诉我们什么。
· 单元测试应可维护且可读
当生产代码更改时,通常需要更新测试,也可能需要调试。因此,不仅对于编写它的人,而且对于其他开发人员,都必须易于阅读和理解该测试。为了清楚和易读,请始终组织和命名测试。
· 单元测试应验证单个用例
好的测试只能验证一件事,而只能验证一件事,这意味着通常情况下,它们只能验证一个用例。遵循此最佳实践的测试更简单,更易理解,这对于可维护性和调试很有好处。验证不止一件事的测试很容易变得复杂且维护耗时。不要让这种情况发生。
另一个最佳实践是使用最少数量的断言。有人建议每个测试只声明一个(可能有点太严格了)。这个想法是集中于仅验证所测试用例所需的内容。
· 单元测试应隔离
测试应该可以在任何机器上以任何顺序运行,而不会互相影响。如果可能,测试应不依赖于环境因素或全局/外部状态。具有这些依赖项的测试较难运行,并且通常不稳定,从而使其更难以调试和修复,最终花费的时间超过了所节省的时间(请参见上面的可信赖信息)。
几年前,马丁·福勒(Martin Fowler)撰写了有关“单独的”与“可社交的”代码的文章,以描述应用程序代码中的依赖关系用法,以及如何相应地设计测试。在他的文章中,“单独的”代码不依赖于其他单元(它更加独立),而“可联系的”代码确实与其他组件交互。如果应用程序代码是单独的,则测试很简单…但是对于正在测试的社交代码,您可以构建“单独”或“社交”测试。“社交测试”将依赖于真实的依赖关系以验证行为,而“单独测试”则将受测代码与依赖关系隔离开。您可以使用模拟来隔离被测代码,并为“可社交”代码构建“单独”测试。我们将在下面查看如何执行此操作。
图1:社交测试与孤立测试。资料来源:马丁·福勒(Martin Fowler),2014年,“UnitTest”
通常,使用模拟作为依赖项会使我们的测试人员生活更加轻松,因为我们可以为社交代码生成“单独的测试”。复杂代码的社交测试可能需要大量设置,并且可能违反隔离和可重复的原则。但是,由于模拟是在测试中创建和配置的,因此它是独立的,我们可以更好地控制依赖项的行为。另外,我们可以测试更多的代码路径。例如,我可以返回自定义值或从模拟中引发异常,以涵盖边界或错误情况。
单元测试应自动化
确保在自动化过程中运行测试。这可以是每天、每小时或在持续集成或交付过程中。团队中的每个人都需要访问并查看报告。作为一个团队,讨论您关心的指标:代码覆盖率、修改后的代码覆盖率、正在运行的测试数量、性能等。
通过查看这些数字可以学到很多东西,这些数字的巨大变化通常表明可以立即解决回归问题。
结合使用单元测试和集成测试
迈克尔·科恩(Michael Cohn)的书《成功实现敏捷:使用Scrum进行软件开发》使用测试金字塔模型解决了这一问题(请参见下图中的插图)。这是描述测试资源理想分配的常用模型。这个想法是,随着您进入金字塔,测试通常会更复杂、更脆弱、运行更慢、调试更慢。较低的级别更加隔离和集成、更快、更易于构建和调试。因此,自动化的单元测试应占您测试的大部分。
单元测试应验证所有细节、极端情况和边界条件等。应更谨慎地使用组件、集成、UI和功能测试,以验证API或应用程序的整体行为。手动测试应该在整个金字塔结构中所占的比例最小,但对于发布验收和探索性测试仍然有用。该模型为组织提供了高度的自动化和测试覆盖范围,因此他们可以扩大测试工作量,并将与构建、运行和维护测试相关的成本降至最低。
单元测试应在有组织的测试实践中执行
为了在各个级别上推动测试的成功,并使单元测试过程具有可扩展性和可持续性,您将需要一些其他实践。首先,这意味着在编写应用程序代码时编写单元测试。一些组织在应用程序代码之前编写测试(测试驱动或行为驱动的编程)。重要的是测试与应用程序代码紧密结合。测试和应用程序代码甚至应该在代码审查过程中一起审查。评论有助于您理解所编写的代码(因为他们可以看到预期的行为)并可以改善测试!
与代码一起编写测试不仅是针对新行为或计划中的更改,对于修复错误也至关重要。您修复的每个错误均应进行测试,以验证该错误是否已修复。这样可以确保该错误在将来保持不变。
对测试失败采取零容忍策略。如果您的团队忽略测试结果,那为什么还要进行测试呢?测试失败应该表明是真正的问题…因此,在浪费质量检查人员的时间之前或更早就解决这些问题,或更糟糕的是,它们会进入发布的产品。
解决故障所需的时间越长,这些故障最终将花费您的组织更多的时间和金钱。因此,在重构期间运行测试,请在提交代码之前立即运行测试,并且在测试通过之前也不要将任务视为“完成”。
最后,维护那些测试。正如我之前说过的,如果您在应用程序更改时没有使这些测试保持最新状态,则它们会失去价值。尤其是如果它们失败了,则失败的测试会浪费时间和金钱进行每次失败的调查。当代码更改时,根据需要重构测试。
如您所见,要使单元测试中的金钱和时间回报最大化,就需要在应用最佳实践方面进行一些投资。但最终,这些回报值得进行初始投资。
那代码覆盖率呢?
通常,代码覆盖率是对自动化测试运行期间执行了多少生产代码的度量。通过运行一组测试并查看代码覆盖率数据,您可以大致了解正在测试的应用程序数量。
代码覆盖范围很多,最常见的是行覆盖范围和分支覆盖范围。大多数工具专注于行覆盖率,它仅告诉您是否覆盖特定行。分支更加精细,因为它告诉您是否覆盖了代码的每个路径。
代码覆盖率是一项重要指标,但是请记住,增加覆盖率是达到目的的一种手段。这对于发现测试中的差距非常有用,但这并不是唯一要关注的事情。注意不要花费太多的精力来尝试达到100%的覆盖率——这甚至可能是不可能或不可行的,实际上,测试的质量是很重要的。话虽如此,为您的项目至少达到60%的覆盖率是一个不错的起点,而设定80%或更高的覆盖率是一个好的目标。显然,由您决定目标是什么。
如果您拥有自动化的工具,这不仅很有价值,它不仅可以测量代码覆盖率,还可以跟踪测试覆盖了多少修改后的代码,因为这可以使您了解是否编写了足够的测试以及生产代码的更改。
在此处查看来自Parasoft的报告和分析中心的示例代码覆盖率报告,如果您正在使用Parasoft Jtest进行单元测试,则可以浏览该示例:
要记住的另一件事是,在编写新测试时,请注意不要只关注行覆盖范围,因为单行代码可能会导致多个代码路径,因此请确保您的测试验证这些代码路径。线覆盖率是一个有用的快速指示器,但这并不是唯一要寻找的东西。
增加覆盖率的最明显方法就是简单地为更多的代码路径添加更多的测试,以及被测方法的更多用例。增加覆盖范围的有效方法是使用参数化测试。对于Junit4,有内置的Junit4参数化功能和诸如JunitParams之类的第三方库。Junit5具有内置的参数化功能。
最后,如果您尚未跟踪测试范围,强烈建议您开始。有很多工具可以提供帮助,例如Parasoft Jtest。首先测量您当前的覆盖范围数字,然后为应该覆盖的范围设定目标,首先解决重要的差距,然后再从那里开始工作。
总结
尽管单元测试是确保软件质量的可靠技术,但仍被认为是开发人员的负担,许多团队仍在为此而苦苦挣扎。为了充分利用测试和自动化测试工具,测试必须是可信赖的、可维护的、可读的、自包含的,并且必须用于验证单个用例。自动化是使单元测试可行和可扩展的关键。
此外,软件团队需要练习良好的测试技术,例如与应用程序代码一起编写和审查测试,维护测试以及确保立即跟踪和纠正失败的测试。采用这些单元测试最佳实践可以快速改善您的单元测试结果。
最后:【可能给予你一定的帮助】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
关注我的微信公众号【软件测试小dao】免费获取~
我的学习交流群:644956177 群里有技术大牛一起交流分享~
如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!
以上是关于测试自动化的 10 个最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
关于自动化单元/集成测试的 SSDT 开发过程和最佳实践的提示