Testcontainers for .NET 错误自动发现未检测到 Docker 主机配置

vah*_*ari 4 asp.net-core testcontainers

我使用Testcontainers.MsSql 3.0.0在 asp.net 项目中进行集成测试。集成测试在 Visual Studio 测试运行器中成功运行。但是当我通过 docker build 命令在docker 桌面版本 20.10.7中运行测试时,出现错误:

\n
\n

自动发现未检测到 Docker 主机配置无法\n检测 Docker 终结点。使用环境变量或 ~/.testcontainers.properties 文件来自定义配置\n

\n
\n

这是container\xe2\x80\x99s创建代码:

\n
Var dbContainer\n                    = new MsSqlBuilder()\n                    .WithImage(imageName)\n                    .WithCleanUp(true)\n                    .Build();\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的 docker 文件:

\n
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env\n\nARG buildVersion\n\nWORKDIR /app\nCOPY . ./\n\nRUN dotnet restore ./Test.sln\n\nRUN dotnet test ./Test.sln /p:CollectCoverage=true \n\nRUN dotnet publish ./Test/ -c Release  -o out\n\nFROM mcr.microsoft.com/dotnet/aspnet:7.0\n\nWORKDIR /app\nCOPY --from=build-env /app/out .\n\nENV TZ=Asia/Tehran\nRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone\nRUN dpkg-reconfigure -f noninteractive tzdata\n\nEXPOSE 80 80/tcp\n\nENTRYPOINT ["dotnet", "Test.dll"]\n
Run Code Online (Sandbox Code Playgroud)\n

我在 github 上搜索,但解决方案对我不起作用。例如,我尝试使用 docker-compose 但它没有 \xe2\x80\x99t 工作:

\n
 version: "3"\nservices:\n  docker_compose_test:\n    build:\n      dockerfile: Dockerfile\n      context: .\n    entrypoint: dotnet\n    command: test\n    environment:\n      - TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal\n    volumes:\n      - $PWD:$PWD\n      - /var/run/docker.sock:/var/run/docker.sock\n
Run Code Online (Sandbox Code Playgroud)\n

是我的完整源代码。

\n

Leo*_*rci 5

我有同样的问题。我希望能给你一些信息来解决这个问题。

\n

如果您尝试使用命令构建 docker 映像docker build -t my-image-name .,您会注意到构建过程在 处失败dotnet test

\n

失败的原因是 TestContainer 正在尝试运行第二个 Docker 容器,但无法与 Dockerd 通信。

\n

如果您查看某些网站(甚至TestContainer dind 文档),他们建议添加卷-v /var/run/docker.sock:/var/run/docker.sock,正如您在发布的 docker compose 中找到的那样。

\n

请注意,此解决方案仅在您运行dotnet testa 时才有效docker run,因为在 a 期间无法添加外部卷docker build

\n

如果您尝试运行 docker-compose up,也会出现同样的问题。您的 docker-compose 有一个构建部分,它表示从您创建的 dockerfile 构建一个容器,并且它会如上所述崩溃。

\n

为什么使用 VS testrunner 运行测试时它可以工作?它之所以有效,是因为您的 testrunner 正在dotnet testdockerd 已经存在的环境中运行。

\n

可能的解决方案:使用多阶段 Dockerfile。

\n

我们可以看到问题是在 docker 构建过程中执行 dotnet test。我们必须在它之后执行。

\n

多阶段 dockerfile 可以帮助我们。以这个 dockerfile 为例:

\n
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS base\nWORKDIR /App\n\nCOPY . ./\nRUN dotnet restore\nRUN dotnet build\n\nFROM base as test\nCMD [ "dotnet", "test" ]\n\n# multiple stages (like publish and so on)\n
Run Code Online (Sandbox Code Playgroud)\n

该 dockerfile 声明了至少 2 个阶段:基础阶段和测试阶段。

\n

请注意,它dotnet test 不再在构建过程中运行,而是在测试阶段运行容器时作为命令运行。

\n

执行命令:

\n

docker build -t my-image-name --target test .创建您的应用程序的映像test stage

\n

现在执行命令:

\n

docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock --name my-container-name my-image-name

\n

Voil \xc3\xa0您的测试正在运行,并且 TestContainer 能够运行另一个 docker 容器!

\n

然后您可以继续执行以下命令构建整个图像:

\n

docker build -t my-image-name .

\n

Docker Compose 解决方案

\n

Docker Compose 的解决方案可能如下:

\n
    \n
  1. 创建一个 dockerfile 仅用于测试目的
  2. \n
  3. 当且仅当基于测试 dockerfile 的容器成功完成时,才运行容器。
  4. \n
\n

这是一个基于上面 dockerfile 的示例。当且仅当从我的 dockerfile 构建的容器(用于运行 dotnet 测试)成功完成时,我的 docker-compose.yml 才会运行容器“docker_hello_world”。

\n
version: "3.8"\nservices:\n  docker_hello_world:\n    image: hello-world\n    depends_on:\n      docker_compose_test:\n        condition: service_completed_successfully\n  docker_compose_test:\n    build:\n      dockerfile: Dockerfile\n      context: .\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n
Run Code Online (Sandbox Code Playgroud)\n

最后你将需要

\n
    \n
  1. 一个 dockerfile,其中包含创建可使用该命令运行的映像的定义dotnet test
  2. \n
  3. 包含构建用于生产的映像的定义的 dockerfile(无需运行 dotnet 测试)
  4. \n
  5. docker-compose.yml,其中您的生产容器取决于基于为测试目的而创建的 docker 映像运行容器的结果。
  6. \n
\n
\n

我希望我能以某种方式帮助你。如果您需要更多信息,请告诉我。

\n

一些参考资料:

\n

https://dotnet.testcontainers.org/examples/dind/

\n

https://docs.docker.com/build/building/multi-stage/

\n

https://docs.docker.com/language/java/run-tests/

\n

https://docs.docker.com/compose/startup-order/

\n