标签:测试
微服务架构中的测试策略
在过去的几年里,基于服务的架构已经转向更小、更专注的“微”服务。这种方法有很多好处,例如能够独立部署、扩展和维护每个组件,以及在多个团队之间并行开发。但是,一旦引入了这些额外的网络分区,适用于单体进程内应用程序的测试策略就需要重新考虑。在这里,我们计划讨论几种方法来管理多个独立可部署组件的额外测试复杂性,以及如何在多个团队各自作为不同服务的守护者的情况下,使测试和应用程序保持正确。
实用的测试金字塔
“测试金字塔”是一个比喻,它告诉我们应该将软件测试分组到不同粒度的桶中。它还提供了一个关于我们在每个组中应该有多少测试的想法。虽然测试金字塔的概念已经存在了一段时间,但团队仍然难以将其正确地付诸实践。本文回顾了测试金字塔的原始概念,并展示了如何将其付诸实践。它展示了你在金字塔的不同层级中应该寻找哪些类型的测试,并提供了关于如何实现这些测试的实际示例。
TDD 死了吗?
Ruby on Rails 的创建者 David Heinemeier Hansson 在 RailsConf 上发表了主题演讲,他在演讲中宣布 TDD 已经死了。这在 Rails 和更广泛的软件开发社区中引起了预料之中的巨大争议。这也引发了 David、Kent 和我之间的一些有趣的对话。我们认为这些对话很有趣,其他人可能也喜欢观看,因此录制了一系列视频聊天,我们在其中讨论了 TDD 在软件开发中的作用。
面向域的可观察性
我们软件系统中的可观察性一直很有价值,并且在这个云和微服务时代变得更加重要。但是,我们添加到系统中的可观察性往往是比较低级的,并且本质上是技术性的,而且很多时候它似乎需要在我们的代码库中散布着笨拙的、冗长的调用,这些调用指向各种日志记录、仪器和分析框架。本文描述了一种模式,它可以清理这种混乱,并允许我们以干净、可测试的方式添加与业务相关的可观察性。
Goto Fail、Heartbleed 和单元测试文化
2014 年初发现了两个计算机安全漏洞:苹果的“goto fail”漏洞和 OpenSSL 的“Heartbleed”漏洞。两者都有可能导致广泛而严重的安全性故障,其全部程度我们可能永远不会知道。鉴于其严重性,软件开发行业必须反思如何才能检测到这些漏洞,以便我们能够在未来提高预防此类缺陷的能力。本文考虑了单元测试可以发挥的作用,展示了单元测试,更重要的是单元测试文化,如何能够识别出这些特定的错误。它继续探讨了这种文化的成本和收益,并描述了这种文化如何在谷歌得到灌输。
消除测试中的非确定性
自动回归套件可以在软件项目中发挥至关重要的作用,它对于减少生产中的缺陷非常有价值,对于演化设计也至关重要。在与开发团队交谈时,我经常听到关于非确定性测试的问题——有时通过有时失败的测试。如果任其发展,非确定性测试会完全破坏自动回归套件的价值。在本文中,我概述了如何处理非确定性测试。最初,隔离有助于减少它们对其他测试的损害,但你仍然需要尽快修复它们。因此,我讨论了针对非确定性的常见原因的治疗方法:缺乏隔离、异步行为、远程服务、时间和资源泄漏。
演示前端
你是否曾经参加过“演示”,开发人员自豪地展示了他们 API 的屏幕接屏幕的 JSON 输出,而用户却感到困惑和分心,无法理解这些输出?你是否曾经尝试在开发中使用 API,却因难以找到正确的 JSON 负载和标头咒语来测试功能而感到沮丧?演示前端是一个简单的 UI,它提供基本功能来演示和探索此类 API。
LLM 应用程序开发的工程实践
LLM 工程不仅仅是提示设计或提示工程。在本文中,我们分享了一套工程实践,这些实践帮助我们在最近的一个项目中快速可靠地交付了一个原型 LLM 应用程序。我们将分享 LLM 应用程序的自动化测试和对抗性测试技术、重构,以及 LLM 应用程序架构和负责任的 AI 的考虑因素。
模拟并非存根
术语“模拟对象”已成为描述用于测试的模拟真实对象的特殊情况对象的流行术语。大多数语言环境现在都有框架,可以轻松创建模拟对象。然而,人们往往没有意识到,模拟对象只是特殊情况测试对象的一种形式,它能够实现不同的测试风格。在本文中,我将解释模拟对象的工作原理,它们如何鼓励基于行为验证的测试,以及围绕它们的社区如何使用它们来开发不同的测试风格。
测试异步 JavaScript
JavaScript 社区似乎存在一个普遍的误解,即测试异步代码需要与测试“常规”同步代码不同的方法。在这篇文章中,我将解释为什么这通常不是这样。我将重点介绍测试支持异步行为的代码单元与测试本质上是异步的代码之间的区别。我还将展示基于 Promise 的异步代码如何适合于清晰简洁的单元测试,这些测试可以以清晰易读的方式进行测试,同时仍然验证异步行为。
持续交付
我们对持续交付进行了为期一小时的概述。主题包括持续交付的理由、部署管道、持续集成、DevOps 和部署策略。重点是 Jez 将发布候选者拟人化为希腊神话中的英雄。
现代模拟工具和黑魔法
现代模拟工具对我们处理遗留代码的能力可能产生的积极影响,以及使用这些工具可能产生的负面影响。
生产中的 QA
传统上,QA 侧重于在软件发布到生产环境之前对其进行测试,以查看它是否已准备好发布。但越来越多的现代 QA 组织也开始关注运行在生产环境中的软件。通过分析日志和其他监控工具,他们发现质量问题,并将其突出显示给开发组织。这种方法对于使用持续交付将新版本的软件快速可靠地发布到生产环境的组织特别有效。
测试影响分析的兴起
测试影响分析 (TIA) 是一种加速构建测试自动化阶段的现代方法。它通过分析源代码的调用图来确定在更改生产代码后应运行哪些测试。微软在这方面做了一些广泛的工作,但开发团队也可以相当便宜地实现一些有用的东西。
敏捷文档
我的同事 Joe Walnes 指出我注意到了我们同事 Chris Stevenson 开发的一个非常简单的工具。TextDox(是 AgileDox 的一部分)是一个从 JUnit 测试用例自动生成文档的工具。听起来很荒谬,但这就是 Wardish 想法的风格。
无断言测试
这是一个来自朋友的朋友的故事。我相信它是真的,至少在某个地方是。
时钟包装器
如果你需要在代码中获取当前日期或时间,不要直接访问系统的例程来获取这些数据。在它周围放置某种包装器,允许你通过将“当前日期/时间”设置为特定值来覆盖它。这对于简化测试很重要。
数据库和构建时间
我最近发现了一个有趣的对比。两个规模相似的企业应用程序项目(约 100 KLOC),类似的环境(Java 和 .NET)。一个可以在一小时内完成完整的构建和测试,另一个需要 2-3 分钟。
不可测试
(这是你字典中的一个补充。)
不可测试(形容词):不可测试的软件。
不稳定的测试失败
前几天我正在处理一些我的书中的示例代码。我做了一些更改,让一切都正常工作,运行了测试,并将其提交到我的个人存储库。然后我转到另一个区域,做了一些更改——之前区域中的一些意外测试失败了。现在,运行自动测试的部分目的是找到意外的故障,但这段书中的代码有完全独立的区域。这很奇怪。
探索性测试
探索性测试是一种测试风格,它强调学习、测试设计和测试执行的快速循环。探索性测试不是试图验证软件是否符合预先编写的测试脚本,而是探索软件的特性,提出发现,然后将这些发现归类为合理的行为或故障。
给定-何时-然后
Given-When-Then 是一种表示测试的风格,或者正如其倡导者所说,使用 示例规范 来指定系统的行为。它是 Daniel Terhorst-North 和 Chris Matts 在 行为驱动开发 (BDD) 中开发的一种方法。它作为许多测试框架(如 Cucumber)的结构化方法出现。您也可以将其视为对 四阶段测试 模式的重新表述。
谦虚对象
某些程序元素本质上难以测试,甚至无法测试。因此,这些元素中的任何逻辑都容易出现错误,并且难以演变。为了缓解此问题,尽可能将逻辑从难以测试的元素中移出,并移入代码库中其他更友好的部分。通过使不可测试的对象变得谦虚,我们减少了它们隐藏错误的可能性。
内存中测试数据库
内存中数据库是一种完全在主内存中运行的数据库,不接触磁盘。它们通常作为嵌入式数据库运行:在进程启动时创建,在该进程中嵌入运行,并在进程结束时销毁。
Junit 新实例
我经常收到围绕 JUnit 测试框架中的一个设计选择之一的问题——为每个测试方法运行创建一个新对象的决定。足以保证一个快速的 bliki 条目。(但是,我几乎不得不指出,我对 JUnit 的写作并不意味着我不认为其他形式的测试很重要。有很多有用的测试活动,虽然 JUnit 及其同类产品对其中许多活动很有价值,但它并不是解决所有问题的方案。有关更多关于测试的博客,我建议您查看 Brett Pettichord、Brian Marick 和 James Bach 的博客。您也不应该假设我对 xUnit 测试的写作暗示了重构、用例或牙线的重要性。)
遗留缝合
在处理遗留系统时,识别和创建缝合线非常有价值:我们可以更改系统行为而无需编辑源代码的地方。找到缝合线后,我们可以使用它来打破依赖关系以简化测试,插入探针以获得可观察性,并将程序流重定向到新模块作为遗留置换的一部分。
制作存根
测试增强型设计的一个常见问题是如何在测试模式下创建服务存根,同时让真实的东西在生产中(以及某些测试中)存在。我的几位同事分享了他们的想法。
纳什维尔项目
我最近花了一些时间与我最喜欢的 Thoughtworks 项目之一在一起。这是一个始于 1998 年的项目,使用当时的新 J2EE 技术。多年来,它有着迷人的历史:从 EJB 开始,将其移除,外包到班加罗尔,然后回到芝加哥。许多人进出该项目,该项目的员工人数在 6 到 60 人之间。总的来说,该项目投入了超过 300 个员工年,代码量约为 100 KLOC。
对象母亲
对象母亲是一种在测试中使用的类,用于帮助创建用于测试的示例对象。
页面对象
当您针对网页编写测试时,您需要引用该网页中的元素才能单击链接并确定显示的内容。但是,如果您编写直接操作 HTML 元素的测试,那么您的测试将对 UI 中的更改很脆弱。页面对象将 HTML 页面或片段包装在特定于应用程序的 API 中,允许您操作页面元素,而无需深入研究 HTML。
自测试代码
自测试代码是我在 重构 中使用的名称,指的是在编写功能软件的同时编写全面的自动化测试的做法。如果做得好的话,这将允许您调用一个执行测试的单个命令——并且您确信这些测试将揭示隐藏在代码中的任何错误。
静态替换
当我听我们的开发团队谈论他们的工作时,一个共同的主题是他们不喜欢静态的东西。通常我们会看到公共服务或组件保存在带有静态初始化器的静态变量中。静态变量(在大多数语言中)的一个主要问题是您无法使用多态性来用另一个实现替换一个实现。这让我们很困扰,因为我们是测试的忠实粉丝——为了很好地测试,能够用 服务存根 替换服务非常重要。
合成监控
合成监控(也称为语义监控)定期对实时生产系统运行应用程序自动化测试的子集。结果被推送到监控服务,如果出现故障,监控服务会触发警报。这种技术将自动化测试与监控相结合,以便检测生产中失败的业务需求。
测试癌症
随着我的职业生涯变成了全职写作,我经常担心自己会远离日常软件开发的现实。我看到其他知名人士与现实脱节,我担心自己也会遭遇同样的命运。我对此最大的抵抗来源是 Thoughtworks,它就像一剂现实的良药,让我脚踏实地。
Thoughtworks 也是该领域想法的来源,我喜欢写一些我的同事发现和开发的有用东西。通常这些都是有帮助的想法,我希望我的读者中的一些人能够使用。我今天的话题不是那么令人愉快。这是一个问题,我们还没有答案。
测试覆盖率
我时不时地听到人们问他们应该追求什么样的测试覆盖率(也称为代码覆盖率),或者自豪地说明他们的覆盖率水平。这些说法都错过了重点。测试覆盖率是查找代码库中未测试部分的有用工具。测试覆盖率作为衡量测试好坏的数值指标几乎没有用处。
测试驱动开发
测试驱动开发 (TDD) 是一种通过编写测试来指导软件开发的软件构建技术。它是由 Kent Beck 在 1990 年代后期作为极限编程的一部分开发的。本质上,我们反复遵循三个简单的步骤
测试不变式
在契约式设计 (DbC) 和测试驱动开发 (TDD) 的倡导者之间,一直存在着一种长期存在的,尽管低调的争论。我现在不会深入探讨这个问题,但我将传递一个将两者合并的想法,这个想法是在我和 Daniel Jackson 交谈时产生的。
测试语言
我目前正在参加 XP 日 的一个会议,Owen Rogers 和 Rob Styles 正在谈论 XP 的单元测试和验收测试之间的区别。这引发了我脑海中的一个想法——编写验收测试的语言应该是什么样的?
测试资源池
我正在翻阅一些旧笔记,偶然发现了一个简单但有用的技巧,这是 Rich Garzaniti 给我的。