使用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 如何使用 Spring Test 进行集成测试

    SpringBoot 如何使用 Spring Test 进行集成测试

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

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

    springBoot集成webSocket并使用postMan进行测试

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

    2024年02月02日
    浏览(6)
  • SpringBoot 如何使用 MockMvc 进行 Web 集成测试

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

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

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

    SpringBoot 如何使用 EmbeddedDatabaseBuilder 进行数据库集成测试

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

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

    SpringBoot 如何使用 TestRestTemplate 进行 RESTful API 集成测试

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

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

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

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

    实战指南:使用 xUnit 和 ASP.NET Core 进行集成测试【完整教程】

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

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

    现代C++编程实战25-两个单元测试库:C++里如何进行单元测试

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

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

    如何进行微服务的集成测试

    集成测试的概念 说到集成测试,相信每个测试工程师并不陌生,它不是一个崭新的概念,通过维基百科定义可以知道它在传统软件测试中的含义。 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日
    浏览(6)
  • cmake应用:集成gtest进行单元测试

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

    2024年02月13日
    浏览(13)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包