自动化测试和可执行规范只能在具有可测试架构的软件上工作。可测试的架构能够实现快速可靠的测试,这些测试易于编写、执行和维护。
快速反馈
快速测试使开发人员能够频繁地运行测试,以获得对其正在构建的内容的快速反馈,而不会失去专注或流程。
可测试性
在设计可测试性时,请确保您的产品和服务由松耦合、封装良好的组件或模块组成。
将您的业务逻辑与您的基础设施(通常是缓慢且脆弱的组件)解耦,可以使您在不同的级别进行测试,从而最大限度地提高信心,并最大程度地降低成本。
- 确保您可以在不使用用户界面(UI)的情况下运行测试。它们速度慢、脆弱、昂贵且难以修复。不要仅仅依赖 UI 测试。
- 针对数据库运行测试会使测试速度变慢。我们需要在每次测试之前确保数据库处于预期的状态,以使测试行为一致。这将确保测试不会相互干扰,并且可以按任何顺序执行。
我们希望大多数测试使用某种内存中存根实现,而不是实际的数据库。从域逻辑的角度来看,行为看起来完全相同。为了确保存根的工作方式与实际情况相同,我们需要有信心,我们可以通过使用契约测试获得信心。
端口和适配器
我们可以将我们的数据库和存根视为可以插入**端口**的两种事物。包含业务逻辑的应用程序不需要知道它是在与存根还是实际数据库通信。这是因为它正在与该端口通信并存储和检索数据。我们可以使用存根和实际实现运行测试。这让我们确信存根的行为与实际情况相同。
业务逻辑位于应用程序的核心,完全与外部设备和服务解耦。它不知道数据库、消息队列或 Web 服务,因为我们通过这些端口将它们隔离了。通常,这些端口连接到与实际实现交互的适配器。将有一个数据库适配器、一个队列适配器和一个 Web 服务适配器。用户界面定义了我们可以与系统交互的方式。它还将有一个适配器,例如一个 Web 服务器,它插入端口以在浏览器中显示 UI。所有 IO 往往发生在这些端口之外。通过直接通过端口测试核心业务逻辑,我们可以消除许多缓慢且脆弱的 IO。
这种架构模式称为**端口和适配器模式**(或六边形架构)。它使您能够在更低的级别连接场景和单元测试,而契约测试则让您对此充满信心。
全栈
您需要运行一些通过整个堆栈深度的测试,以获得完全的信心。诊断全栈端到端测试中的问题非常困难,因为它可能出现在任何地方。这些测试很脆弱,因为一个更改可能会破坏所有测试。它们也很慢,因为在通过浏览器、Web 服务或数据库时会涉及 IO。
测试金字塔
专注于拥有不同类型的测试:大量的单元测试,一些不通过所有繁重基础设施组件的测试,以及一些通过 UI 的测试。这被称为测试金字塔。
更多信息
有关如何实现快速测试(在 node.js 中)的示例,请参阅GitHub 上的 subsecondtdd。
或者看看 Aslak 在Devlin 2017 上的演讲 - 或幻灯片 - 关于这个主题。