使用Docker进行C#集成测试:高级技术

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

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

开始课程

使用Docker进行C#集成测试:高级水平



集成测试是C#开发中至关重要的阶段,它允许检查系统组件与真实依赖项(如数据库、消息队列、外部API)的交互。使用Docker进行此目的已成为行业标准,但在高级水平上,会出现隔离、性能和并行执行的问题。在本文中,我们将使用Testcontainers库和高级配置,剖析使用Docker进行C#集成测试的专业技术。



1. 为.NET配置Testcontainers:基础基础设施



用于.NET的Testcontainers库允许在测试环境中以编程方式管理Docker容器。与手动运行docker-compose不同,Testcontainers会自动为每个测试类或模块启动和停止容器,确保环境清洁。



通过NuGet安装包:

dotnet add package Testcontainers --version 3.9.0dotnet add package Testcontainers.PostgreSql --version 3.9.0dotnet add package Testcontainers.MsSql --version 3.9.0


使用PostgreSQL的集成测试基类示例:

using Testcontainers.PostgreSql;using Xunit;

public class DatabaseFixture : IAsyncLifetime{ private readonly PostgreSqlContainer _container = new PostgreSqlBuilder() .WithImage("postgres:15-alpine") .WithDatabase("testdb") .WithUsername("testuser") .WithPassword("testpass") .Build();

public string ConnectionString => _container.GetConnectionString();

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

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


现在,每个测试类都可以使用此fixture来获取隔离的数据库实例。



2. 测试隔离和容器状态管理



高级水平需要对隔离进行精细控制。不要为整个测试套件使用一个容器,而是为每个测试类甚至每个测试使用一个容器。这可以防止测试之间数据库的“脏”状态。



通过xUnit中的Collection属性实现:

[CollectionDefinition("Database collection")]public class DatabaseCollection : ICollectionFixture<DatabaseFixture>{}

[Collection("Database collection")]public class UserRepositoryTests{ private readonly DatabaseFixture _fixture;

public UserRepositoryTests(DatabaseFixture fixture) { _fixture = fixture; }

[Fact] public async Task CreateUser_ShouldPersistUser() { // Arrange await using var context = new AppDbContext(_fixture.ConnectionString); await context.Database.EnsureCreatedAsync(); var repo = new UserRepository(context);

// Act var user = new User { Name = "Test User" }; await repo.CreateAsync(user);

// Assert var savedUser = await context.Users.FindAsync(user.Id); Assert.NotNull(savedUser); }}


为了在测试级别实现完全隔离,使用ITestOutputHelper并在DisposeAsync方法内创建容器:

public class IsolatedTest : IAsyncLifetime{    private PostgreSqlContainer _container;

public async Task InitializeAsync() { _container = new PostgreSqlBuilder().Build(); await _container.StartAsync(); }

public async Task DisposeAsync() { await _container.DisposeAsync(); }}


3. 并行运行测试和资源管理



主要挑战之一

博客

书籍推荐