C# 与 Docker 集成测试:从 A 到 Z 完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# 与 Docker 集成测试:从 A 到 Z



集成测试是任何严肃 C# 应用程序开发中至关重要的阶段。它检查系统的各个组件(数据库、外部 API、文件系统)如何协同工作。然而,测试环境的配置常常令人头疼:需要启动真实的服务器、测试后清理数据,并应对环境的不稳定性。Docker 通过提供轻量、隔离且可重现的容器解决了这些问题。在本文中,我们将详细讲解如何从零开始配置 C# 与 Docker 的集成测试,直至构建一个可用的流水线。



为什么 Docker 是 C# 集成测试的理想选择?



传统方法是使用本地 SQL Server 数据库或外部服务的模拟器。这会导致以下问题:

  • 数据污染:测试会在数据库中留下垃圾数据,影响其他测试。
  • 环境不兼容:开发人员机器上的 DBMS 版本与 CI 服务器上的不同。
  • 并行运行困难:测试会因端口和资源冲突。


Docker 可以轻松解决这些问题:每个测试(或测试组)都会获得自己独立的容器,其中包含所需版本的数据库、Redis 或其他服务。容器轻量、启动迅速,并在测试完成后保证被销毁。对于 .NET 开发者来说,这尤其重要,得益于 Testcontainers for .NET 库,它可以直接从测试代码中自动管理容器。



项目配置:将 Docker 添加到 C# 测试中



首先,我们创建一个包含集成测试的项目。假设我们有一个基于 .NET 8 的 Web API,它与 PostgreSQL 配合使用。我们需要测试创建用户的端点。



步骤 1:安装 NuGet 包

将以下包添加到测试项目中:

dotnet add package Testcontainers.PostgreSqldotnet add package Microsoft.AspNetCore.Mvc.Testingdotnet add package FluentAssertions


Testcontainers.PostgreSql 是 Docker SDK 的一个封装,用于管理 PostgreSQL 容器。Microsoft.AspNetCore.Mvc.Testing 允许在内存中运行 Web 应用程序以进行测试。



步骤 2:创建测试基类

创建一个抽象类,用于在测试前启动数据库容器:

using Testcontainers.PostgreSql;using Xunit;

public abstract class IntegrationTestBase : IAsyncLifetime{ private readonly PostgreSqlContainer _postgresContainer;

protected string ConnectionString => _postgresContainer.GetConnectionString();

protected IntegrationTestBase() { _postgresContainer = new PostgreSqlBuilder() .WithImage("postgres:16-alpine") .WithDatabase("testdb") .WithUsername("test") .WithPassword("test123") .Build(); }

public async Task InitializeAsync() { await _postgresContainer.StartAsync(); }

public async Task DisposeAsync() { await _postgresContainer.StopAsync(); }}


该类实现了 xUnit 中的 IAsyncLifetime 接口,确保在所有测试之前启动容器,并在测试之后停止容器。ConnectionString 从容器动态获取——端口可以是任意空闲端口。



步骤 3:使用 Testcontainers 和 WebApplicationFactory 编写测试

现在编写测试本身。我们将使用 WebApplicationFactory 创建测试 HTTP 客户端:

using Microsoft.AspNetCore.Mvc.Testing;using FluentAssertions;using System.Net.Http.Json;

public class UserApiTests : IntegrationTestBase{ private readonly WebApplicationFactory<Program> _factory;

public UserApiTests()

博客

书籍推荐