You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker构建中.NET测试失败时,如何将测试报告复制到Agent?

问题场景

我通过Docker运行基于Specflow+Runner的C#自动化测试用例,借助Azure DevOps的master.yml流水线文件,使用共享Agent构建Docker镜像。当前Dockerfile里写了四种测试执行方式,但核心需求是:即使Dockerfile中的测试用例执行失败,也要能把测试报告复制到Agent机器上。

现有配置文件如下:

原master.yml

jobs:
  - job: run_docker_build
    displayName: Run UI Build
    steps:
#------------------------------------------
# Build Docker
#------------------------------------------
      - task: Docker@2
        displayName: DockerBuild
        env:
         COMPOSE_DOCKER_CLI_BUILD: 1
         DOCKER_BUILDKIT: 1
        inputs:
         containerRegistry: "XXX"
         repository: run-automation-ui
         command: build
         Dockerfile: '**/Dockerfile'
         tags: |
          latest
          $(Build.BuildId)

#------------------------------------------
# Copy the Results from Build Image
#------------------------------------------
      - pwsh: |
         $id=docker images --filter "label=Test=True" -q | Select-Object -First 1
         docker create --name testcontainer $id
         docker cp testcontainer:/src/AutomationTests/TestResults ./TestResults
         docker cp testcontainer:/src/AutomationTests/TestResults/Screenshots ./Screenshots
         docker rm testcontainer
        displayName: 'Copy Test Results'
        condition: always()
#------------------------------------------
# Publishing Test Results
#------------------------------------------
      - task: PublishTestResults@2
        inputs:
         testResultsFormat: 'VSTest'
         testResultsFiles: '**/*.trx'
         searchFolder: '$(System.DefaultWorkingDirectory)/TestResults'
         publishRunAttachments: true
        displayName: 'Publish Test Results' 
        condition: always()

原Dockerfile

LABEL Test=True
##Method one (#Even if test fails the build task will finish and in later stage I can copy the Results ) 
#RUN dotnet test -c Release --no-build --logger "trx;LogFileName=/src/AutomationTests/TestResults/test_results.trx" --filter TestCategory=DockerTest || true 

#Method Two (#Even if test fails the build task will finish and in later stage I can copy the Results )
#RUN dotnet test -c Release --no-build --logger "trx;LogFileName=/src/AutomationTests/TestResults/test_results.trx" --filter TestCategory=DockerTest; exit 0 

#Method Three (#Even if test fails the build task will finish and in later stage I can copy the Results )
#RUN dotnet test -c Release --no-build --logger "trx;LogFileName=/src/AutomationTests/TestResults/test_results.trx" --filter TestCategory=DockerTest; \
#echo $? > /dotnet.exitcode;
#RUN exit $(cat /dotnet.exitcode)

#Method Four (if test fails means still i need to able to copy the results )
#RUN dotnet test -c Release --no-build --logger "trx;LogFileName=/src/AutomationTests/TestResults/test_results.trx" --filter TestCategory=DockerTest
解决方案

核心问题是:Docker构建过程中,如果RUN指令返回非0退出码,构建会直接中断,导致后续复制报告的步骤根本无法触发。所以需要做到两点:

  1. 让Docker构建即使测试失败也能完成,确保测试报告被保留在镜像中
  2. 保留测试失败的状态,让流水线最终能反映真实的测试结果

1. 调整Dockerfile的测试执行逻辑

推荐使用改进后的方法三,既保证构建完成,又保留测试的真实退出码:

LABEL Test=True
# 执行测试,保存退出码到文件,确保构建不中断
RUN dotnet test -c Release --no-build --logger "trx;LogFileName=/src/AutomationTests/TestResults/test_results.trx" --filter TestCategory=DockerTest; \
    echo $? > /dotnet.exitcode
# 不直接退出,让构建完成,后续流水线读取退出码判断结果

为什么不用其他方法?

  • 方法一/二:用|| true或exit 0强制让RUN指令返回0,会掩盖测试失败的真实状态,流水线会误判为构建成功
  • 方法四:测试失败直接中断构建,镜像构建不完成,根本拿不到测试报告

2. 优化流水线步骤(master.yml)

在复制测试报告后,读取Docker镜像中保存的退出码,让流水线最终状态匹配测试结果:

jobs:
  - job: run_docker_build
    displayName: Run UI Build
    steps:
#------------------------------------------
# Build Docker
#------------------------------------------
      - task: Docker@2
        displayName: DockerBuild
        env:
         COMPOSE_DOCKER_CLI_BUILD: 1
         DOCKER_BUILDKIT: 1
        inputs:
         containerRegistry: "XXX"
         repository: run-automation-ui
         command: build
         Dockerfile: '**/Dockerfile'
         tags: |
          latest
          $(Build.BuildId)
        # 允许构建完成(Dockerfile里不会中断),后续步骤判断测试结果
        continueOnError: true

#------------------------------------------
# Copy the Results from Build Image
#------------------------------------------
      - pwsh: |
         $id=docker images --filter "label=Test=True" -q | Select-Object -First 1
         if (-not $id) {
             Write-Error "No test image found"
             exit 1
         }
         docker create --name testcontainer $id
         # 复制测试报告
         docker cp testcontainer:/src/AutomationTests/TestResults ./TestResults
         docker cp testcontainer:/src/AutomationTests/TestResults/Screenshots ./Screenshots
         # 读取测试退出码
         $exitCode = docker exec testcontainer cat /dotnet.exitcode
         docker rm testcontainer
         # 将退出码传递给后续步骤
         Write-Host "##vso[task.setvariable variable=TestExitCode;]$exitCode"
        displayName: 'Copy Test Results'
        condition: always()

#------------------------------------------
# 根据测试退出码设置流水线状态
#------------------------------------------
      - pwsh: |
         if ($env:TestExitCode -ne 0) {
             Write-Error "Automation tests failed with exit code $env:TestExitCode"
             exit 1
         }
        displayName: 'Check Test Result'
        condition: always()

#------------------------------------------
# Publishing Test Results
#------------------------------------------
      - task: PublishTestResults@2
        inputs:
         testResultsFormat: 'VSTest'
         testResultsFiles: '**/*.trx'
         searchFolder: '$(System.DefaultWorkingDirectory)/TestResults'
         publishRunAttachments: true
        displayName: 'Publish Test Results' 
        condition: always()

关键优化点:

  • 在Docker Build步骤添加continueOnError: true,确保即使测试失败(Dockerfile里的退出码会被保存,但构建本身完成),流水线能继续执行后续步骤
  • 复制报告时读取镜像中的/dotnet.exitcode文件,将其设置为流水线变量
  • 添加专门的步骤判断测试退出码,如果非0则让流水线失败,保证最终状态真实反映测试结果
  • 所有涉及报告复制和发布的步骤都保留condition: always(),确保无论前面步骤如何都执行

内容的提问来源于stack exchange,提问作者srikanth reddy karumuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:06:47