【问题标题】:Unable to Stop Testcontainers Container in .NET Using MSTest无法使用 MSTest 在 .NET 中停止 Testcontainers 容器
【发布时间】:2022-12-29 21:04:33
【问题描述】:

我正在使用 dotnet Testcontainers 库在 Docker 中启动 SQL Server 数据库以进行集成测试。我正在使用 MSTest 框架。

我的想法是在容器启动的地方运行TestInitialize,填充数据库并在测试方法中运行断言,然后在最后运行TestCleanup,这将停止容器并处理它。

然而,容器在 Docker 中启动并且测试挂起(我猜它永远不会因为某种原因结束运行)。此外,我不是 100% 确定如何填充数据库(我找不到任何用于初始化和 SQL 脚本的命令)。

这是代码:

[TestClass]
public class WithFixtureData
{
    private static readonly TestcontainersContainer _dbContainer =
        new TestcontainersBuilder<TestcontainersContainer>()
        .WithImage("mcr.microsoft.com/mssql/server")
        .WithEnvironment("Database", "Master")
        .WithEnvironment("User Id", "SA")
        .WithEnvironment("Password", "YourSTRONG!Passw0rd")
        .WithCleanUp(true)
        .Build();

    [TestInitialize]
    public async Task StartContainer()
    {
        await _dbContainer.StartAsync();
        ///container starts
    }

    [TestMethod]
    public async Task ShouldBringCorrectFixturesBack()
    {
        ///populate db and run assertions. This code never seems to run
    }

    [TestCleanup]
    public async Task DisposeContainer()
    {
        await _dbContainer.StopAsync();
        ///this part of the code never seems to be executed either
    }
}

【问题讨论】:

  • 您的容器是否正在构建和启动?如果您阅读了mcr.microsoft.com/mssql/server文档,您至少需要提供.WithEnvironment("ACCEPT_EULA", "Y").WithEnvironment("MSSQL_SA_PASSWORD", "YourSTRONG!Passw0rd")。要从容器外部访问,您可能还需要 .WithExposedPorts(1433) 或类似名称,然后是 .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(1433)) 以等待 SQL Server 服务侦听该端口并准备好接受连接。
  • 您应该使用您通常使用的任何机制来填充您的数据库。测试容器的工作只是为您提供一个带有正在运行的数据库实例的容器。
  • @KevinWittek Yup 明白了......我只是在尝试设置测试,以便它在测试类初始化时启动一个容器,然后在所有方法运行后停止它。
  • 你说它挂了。这是否意味着它会无限期挂起?因为你最终应该会遇到超时。共享容器日志也有助于调试。此外,请参阅之前关于使用正确的 WaitStrategy 的评论。您可以在这篇博文中找到一个工作示例:atomicjar.com/2022/10/hello-dotnet

标签: c# .net sql-server mstest testcontainers


【解决方案1】:

我想知道上面的例子是如何运行的,配置看起来不对。我在下面附上了一个工作示例,但首先,让我们看一下这些问题:

  1. 环境变量不存在。 mcr.microsoft.com/mssql/server 图像具有以下 environment variables(请参阅部分环境变量) 在 Linux 容器上配置 SQL Server。这部分如何使用此图片也可能有帮助。要运行容器,至少需要以下配置:

    .WithEnvironment("ACCEPT_EULA", "Y")
    .WithEnvironment("MSSQL_SA_PASSWORD", "yourStrong(!)Password")
    
  2. 数据库端口未公开,您无法连接到数据库。要公开容器端口并将其绑定到随机公共主机端口,请使用.WithPortBinding(1433, true)Here 是另一个展示如何公开容器端口的示例。

  3. 您的配置不使用等待策略来指示容器内运行的服务就绪。 SQL Server 的等待策略可能类似于:

    .WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("/opt/mssql-tools/bin/sqlcmd", "-S", "localhost,1433", "-U", "sa", "-P", "yourStrong(!)Password"))
    

    工作配置将类似于:

    [TestClass]
    public sealed class SO
    {
      private const string Database = "master";
    
      private const string Username = "sa";
    
      private const string Password = "yourStrong(!)Password";
    
      private const ushort MssqlContainerPort = 1433;
    
      private readonly TestcontainersContainer _dbContainer =
        new TestcontainersBuilder<TestcontainersContainer>()
          .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
          .WithPortBinding(MssqlContainerPort, true)
          .WithEnvironment("ACCEPT_EULA", "Y")
          .WithEnvironment("MSSQL_SA_PASSWORD", Password)
          .WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("/opt/mssql-tools/bin/sqlcmd", "-S", $"localhost,{MssqlContainerPort}", "-U", Username, "-P", Password))
          .Build();
    
      [TestInitialize]
      public Task StartContainer()
      {
        return _dbContainer.StartAsync();
      }
    
      [TestCleanup]
      public Task DisposeContainer()
      {
        return _dbContainer.StopAsync();
      }
    
      [TestMethod]
      public Task Question_74323116()
      {
        var connectionString = $"Server={_dbContainer.Hostname},{_dbContainer.GetMappedPublicPort(MssqlContainerPort)};Database={Database};User Id={Username};Password={Password};";
    
        using (var sqlConnection = new SqlConnection(connectionString))
        {
          try
          {
            sqlConnection.Open();
          }
          catch
          {
            Assert.Fail("Could not establish database connection.");
          }
        }
    
        return Task.CompletedTask;
      }
    }
    

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2020-02-10
    • 1970-01-01
    • 2021-08-20
    • 2021-12-21
    • 1970-01-01
    相关资源
    最近更新 更多