使用TestContainers在Docker中进行集成测试

这篇具有很好参考价值的文章主要介绍了使用TestContainers在Docker中进行集成测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

现代软件应用很少独立工作。典型的应用程序会与几个外部系统进行通信,如:

  • 数据库、
  • 消息系统、
  • 缓存提供商
  • 其他第三方服务。

你应该编写测试确保一切正常运行。

单元测试有助于隔离地测试业务逻辑,不涉及任何外部服务。它们易于编写并提供几乎即时的反馈。

有了单元测试还不够,集成测试用来验证与外部系统的交互情况,让你对你的应用程序完全有信心。

所以,在本周的时事通讯中,我将向你展示如何使用Docker进行集成测试。我们需要以下组件

  • TestContainers
  • Docker
  • xUnit

TestContainers是什么

Testcontainers 是一个用于使用临时 Docker 容器编写测试的库。

集成测试是“困难”的,因为你需要维护测试基础设施。在运行测试之前,你需要确保数据库已启动并正在运行。你还必须为测试提供所需的任何数据。如果你的测试在同一数据库上并行运行,它们可能会相互干扰。

一个可能的解决方案是使用所需服务的内存中变体。但这与使用mocks并没有太大的不同。内存中的服务可能没有生产服务的所有功能。

Testcontainers 通过使用 Docker 来启动真实服务来解决这个问题,以进行集成测试。

下面是创建 SQL Server 容器的示例:

MsSqlContainer dbContainer = new MsSqlBuilder()
    .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
    .WithPassword("Strong_password_123!")
    .Build();

之后,你可以使用 MsSqlContainer 实例来获取运行在容器内部的数据库的连接。 这是一个真实的SQL Server数据库,而不是内存数据库。

自定义 WebApplicationFactory:

ASP.NET Core 提供了一个内存测试服务器,我们可以用它来启动一个应用程序实例来运行测试。Microsoft.AspNetCore.Mvc.Testing 包提供了我们将用作实现基础的 WebApplicationFactory 类。

WebApplicationFactory<TEntryPoint> 用于为集成测试创建一个 TestServer

IntegrationTestWebAppFactory 进行以下工作:

  • 创建并配置MySqlContainer实例
  • 调用ConfigureTestServices 用容器中的数据库来设置EF Core
  • 用IAsyncLifetime来控制容器实例的启动/停止
public class IntegrationTestWebAppFactory
    : WebApplicationFactory<Program>,
      IAsyncLifetime
{
    private readonly MsSqlContainer _dbContainer = new MsSqlBuilder()
        .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
        .WithPassword("Strong_password_123!")
        .Build();

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(services =>
        {
            var descriptorType =
                typeof(DbContextOptions<ApplicationDbContext>);

            var descriptor = services
                .SingleOrDefault(s => s.ServiceType == descriptorType);

            if (descriptor is not null)
            {
                services.Remove(descriptor);
            }

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(_dbContainer.GetConnectionString()));
        });
    }

    public Task InitializeAsync()
    {
        return _dbContainer.StartAsync();
    }

    public new Task DisposeAsync()
    {
        return _dbContainer.StopAsync();
    }
}

MsSqlContainer 有一个 GetConnectionString 方法,用于获取当前容器的连接字符串。连接字符串可能会在测试之间发生变化,因为每个测试类都会创建一个单独的容器实例。在同一测试类中的测试案例将使用相同的容器实例。因此,如果你需要在测试之间进行清理,请记住这一点。

另一件事是Data Migration。你必须在每次测试之前显示运行,以创建所需的数据库结构。

使用 IAsyncLifetime 异步启动容器实例。在运行任何测试之前,容器是在 StartAsync 中启动的。而它是在 StopAsync 中停止的。

创建测试基类

测试基类将实现一个类固件接口 IClassFixture。并在测试用例之间提供共享的对象实例。这是实例化大多数测试所需的任何服务的地方。

例如,我正在创建一个 IServiceScope,用于在测试中解析scoped services。

  • ISender 用来发送command和queries
  • ApplicationDbContext 用来设置数据库或者验证结果
public abstract class BaseIntegrationTest
    : IClassFixture<IntegrationTestWebAppFactory>,
      IDisposable
{
    private readonly IServiceScope _scope;
    protected readonly ISender Sender;
    protected readonly ApplicationDbContext DbContext;

    protected BaseIntegrationTest(IntegrationTestWebAppFactory factory)
    {
        _scope = factory.Services.CreateScope();

        Sender = _scope.ServiceProvider.GetRequiredService<ISender>();

        DbContext = _scope.ServiceProvider
            .GetRequiredService<ApplicationDbContext>();
    }

    public void Dispose()
    {
        _scope?.Dispose();
        DbContext?.Dispose();
    }
}

 文章来源地址https://www.toymoban.com/news/detail-712230.html

现在万事俱备,可以写测试用例了。

编写测试用例

这里有一个ProductTests类,里面有一个集成测试的用例,我们使用Arragne, Act, Assert结构。

public class ProductTests : BaseIntegrationTest
{
    public ProductTests(IntegrationTestWebAppFactory factory)
        : base(factory)
    {
    }

    [Fact]
    public async Task Create_ShouldCreateProduct()
    {
        // Arrange
        var command = new CreateProduct.Command
        {
            Name = "AMD Ryzen 7 7700X",
            Category = "CPU",
            Price = 223.99m
        };

        // Act
        var productId = await Sender.Send(command);

        // Assert
        var product = DbContext
            .Products
            .FirstOrDefault(p => p.Id == productId);

        Assert.NotNull(product);
    }
}

结束语

Testcontainers 是使用 Docker 编写集成测试的出色解决方案。你可以启动并配置任何 Docker 镜像,并从你的应用程序中使用它。这比使用模拟或内存变体要好得多,它们缺乏许多功能。

如果你有一个支持 Docker 的 CI/CD 流水线,Testcontainers 将开箱即用。

有几个集成测试可以大大增强你对系统的信心。

 

 

到了这里,关于使用TestContainers在Docker中进行集成测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot 如何使用 MockMvc 进行 Web 集成测试

    SpringBoot 是一个流行的 Java Web 开发框架,它提供了一些强大的工具和库,使得开发 Web 应用程序变得更加容易。其中之一是 MockMvc,它提供了一种测试 SpringBoot Web 应用程序的方式,可以模拟 HTTP 请求和响应的行为。 在本文中,我们将介绍 SpringBoot 中的 MockMvc,演示如何使用它

    2024年02月16日
    浏览(48)
  • springBoot集成webSocket并使用postMan进行测试

    简单来讲,webSocket是一种在http协议基础上的另一种新协议,叫ws协议。 http协议是单工通信,客户端发起请求,服务端收到请求并处理,返回给客户端,然后客户端收到服务端的请求。 ws协议是全双工通信,客户端发起请求后,相当于搭建了一个通道,在不断开的情况下,在

    2024年02月02日
    浏览(43)
  • SpringBoot 如何使用 Spring Test 进行集成测试

    在开发过程中,单元测试是不可或缺的,它可以帮助我们及时发现代码的问题并进行修复,从而提高代码的质量和可维护性。但是,单元测试只能测试单个方法或类的功能,无法测试多个模块之间的交互和整个应用程序的功能。因此,为了确保应用程序的正确性和健壮性,我

    2024年02月10日
    浏览(48)
  • SpringBoot 如何使用 EmbeddedDatabaseBuilder 进行数据库集成测试

    在开发 SpringBoot 应用程序时,我们通常需要与数据库进行交互。为了确保我们的应用程序在生产环境中可以正常工作,我们需要进行数据库集成测试,以测试我们的应用程序是否能够正确地与数据库交互。在本文中,我们将介绍如何使用 SpringBoot 中的 EmbeddedDatabaseBuilder 来进行

    2024年02月16日
    浏览(57)
  • SpringBoot 如何使用 TestRestTemplate 进行 RESTful API 集成测试

    在使用 SpringBoot 开发 RESTful API 的过程中,我们需要进行集成测试,以确保 API 的正确性和可用性。而 TestRestTemplate 是 Spring Framework 提供的一个工具类,可以用来进行 RESTful API 的集成测试。在本文中,我们将介绍如何使用 TestRestTemplate 进行 RESTful API 集成测试。 TestRestTemplate 是

    2024年02月13日
    浏览(75)
  • 使用 Spring Kafka 进行非阻塞重试的集成测试

    ​Kafka的非阻塞重试是通过为主题配置重试主题来实现的。如果需要,还可以配置额外的死信主题。如果所有重试都耗尽,事件将被转发到DLT。在公共领域中有很多资源可用于了解技术细节。对于代码中的重试机制编写集成测试确实是一项具有挑战性的工作。以下是一些测试

    2024年02月10日
    浏览(38)
  • 实战指南:使用 xUnit 和 ASP.NET Core 进行集成测试【完整教程】

    集成测试可在包含应用支持基础结构(如数据库、文件系统和网络)的级别上确保应用组件功能正常。 ASP.NET Core 通过将单元测试框架与测试 Web 主机和内存中测试服务器结合使用来支持集成测试。 集成测试与单元测试相比,能够在更广泛的级别上评估应用的组件,确认多个

    2024年04月22日
    浏览(44)
  • 现代C++编程实战25-两个单元测试库:C++里如何进行单元测试

    你好,我是吴咏炜。 单元测试已经越来越成为程序员工作密不可分的一部分了。在 C++ 里,我们当然也是可以很方便地进行单元测试的。今天,我就来介绍两个单元测试库:一个是 Boost.Test [1],一个是 Catch2 [2]。 单元测试库有很多,我选择 Boost 的原因我在上一讲已经说过:“

    2024年02月07日
    浏览(41)
  • 如何进行微服务的集成测试

    集成测试的概念 说到集成测试,相信每个测试工程师并不陌生,它不是一个崭新的概念,通过维基百科定义可以知道它在传统软件测试中的含义。 Integration testing (sometimes called integration and testing, abbreviated IT) is the phase in software testing in which individual software modules are combined and

    2024年02月11日
    浏览(52)
  • cmake应用:集成gtest进行单元测试

    编写代码有bug是很正常的,通过编写完备的单元测试,可以及时发现问题,并且在后续的代码改进中持续观测是否引入了新的bug。对于追求质量的程序员,为自己的代码编写全面的单元测试是必备的基础技能,在编写单元测试的时候也能复盘自己的代码设计,是提高代码质量

    2024年02月13日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包