第 9 章 并发代码测试的挑战

在前几章中,我们涵盖了测试驱动开发(TDD)实践者测试应用程序所需的所有基本知识。我们学习了如何在开发阶段对代码进行单元测试,如何对较大的组件进行集成测试,以及如何对整个服务进行端到端测试。这些是构建和运行任何软件项目的基本构建块。测试套件使我们能够验证应用程序是否按照客户的要求运行。

随着系统的增长和成熟,开发人员不可避免地需要考虑如何更改和演进他们的代码,以确保系统保持高性能和可扩展性。正如第 7 章《Go 中的重构》中所讨论的,我们可以使用一些常见的重构技术来使代码更改过程更加容易。一种常见的系统重构技术是拆分单体应用程序并用微服务架构替换它们。在第 8 章《测试微服务架构》中,我们学习了如何拆分 BookSwap 应用程序,并使用新引入的契约测试技术来测试微服务之间的集成。

当我们进入微服务架构的世界时,测试变得更加困难,这主要由于两个关键方面:服务由组织内的团队更改,而没有中央监督;操作顺序不再能够保证。我们在前几章中已经涵盖了集成测试的方面,但我们尚未探讨操作顺序变化带来的困难。最重要的是,我们需要探讨如何处理不同操作顺序可能使应用程序进入的不同状态。

本章将探讨并发代码的实现和测试。我们将首先讨论 Go 的并发机制,这是 Go 编程语言的主要优势之一。然后,我们将探讨一些常见的并发示例。我们将学习如何使用 Go 的竞态检测器,这是 Go 工具链的一部分。最后,我们将讨论哪些并发条件无法测试,并了解如何在 BookSwap 应用程序中检测并发问题。

在本章中,我们将涵盖以下主题:

  • Go 的并发机制goroutinechannel 和同步原语

  • 应用并发示例和模式,包括创建线程安全的数据结构

  • 并发代码的不可测试条件:竞态条件、死锁和饥饿

  • Go 竞态检测器的使用和局限性

  • 检测和修复 BookSwap 应用程序中的并发问题

技术要求

您需要安装 Go 1.19 或更高版本 才能运行本章中的代码示例。安装过程可以在官方 Go 文档中找到: https://go.dev/doc/install

本书中包含的代码示例可在以下 GitHub 仓库中公开获取: https://github.com/PacktPublishing/Test-Driven-Development-in-Go/chapter09