当我的 Jest 单元测试在 Docker 中失败时,如何获得测试报告?

How do I get a test report when my Jest unit tests fail in Docker?

我已经创建了一个 React 应用程序,并使用 Docker 在 Azure DevOps 中设置了一个完全可用的管道来构建、测试和发布我的应用程序。

我的管道 yaml 文件中的片段:

#----------------------------------------------------------------------
# Build the docker image
#----------------------------------------------------------------------
- task: Docker@2
  inputs:
    containerRegistry: 'XXXcontainerrepo'
    repository: 'XXX'
    command: 'build'
    Dockerfile: '**/production.Dockerfile'
    tags: |
      $(Build.BuildNumber)
    arguments: '--build-arg buildNumber="$(Build.BuildNumber)"'
  displayName: 'Docker build'
#----------------------------------------------------------------------
# Export and publish test results
#----------------------------------------------------------------------
- script: |
    export id=$(docker images --filter "label=test=$(Build.BuildNumber)" -q | head -1)
    echo "Container ID: ${id}"
    docker create --name testcontainer $id
    docker cp testcontainer:/app/coverage ./coverage
    docker cp testcontainer:/app/junit.xml ./junit.xml
    docker rm testcontainer
  displayName: 'Copy test results and code coverage reports'

- task: PublishCodeCoverageResults@1
  inputs:
    codeCoverageTool: 'cobertura'
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
  displayName: 'Publish code coverage reports'

- task: PublishTestResults@2
  inputs:
    testResultsFormat: 'JUnit'
    testResultsFiles: '**/junit.xml'
    mergeTestResults: true
    failTaskOnFailedTests: true
    testRunTitle: 'Jest Unit Tests'
  displayName: 'Publish test results'

来自 Docker 文件的片段:

# run tests
LABEL test=$buildNumber
RUN npm run test -- --reporters=default --reporters=jest-junit --coverage --watchAll=false

当所有测试用例都通过时,会生成一份测试报告,然后我将其从我的 Docker 容器中复制出来,并使用 Azure 管道中的任务进行发布。

但是当测试失败时,我在 Docker 容器中收到一个错误,并且我的构建失败,没有创建任何报告。当然,我可以在管道构建日志中看到失败的测试,但我没有在 Azure DevOps 中获得可用的报告,因为它从未创建过,因此无法发布。

当我 运行 在本地执行相同的命令时,我会在两种情况下创建一个测试报告,当所有测试通过或当一个或多个测试失败时。

所以我的问题是,即使使用 Docker 的一项或多项测试失败,是否可以创建报告?据我了解,失败测试的数量是退出代码,当退出代码 != 0 时,Docker 容器失败。

我仍然希望 Docker 构建步骤在创建报告后失败,但如果这是不可能的,我在测试结果发布任务中设置了一个标志,如果有的话,构建失败或更多测试失败。 failTaskOnFailedTests: true

更新

continueOnError: true 标志添加到 Docker 构建步骤时,构建会继续下一步,但问题仍然存在。似乎测试 运行 在创建测试和覆盖率报告之前已停止,可能是由于它生成的非零退出代码导致 Docker 步骤退出。

在复制测试结果步骤中,我得到了这个输出:

Error: No such container:path: testcontainer:/app/coverage
Error: No such container:path: testcontainer:/app/junit.xml

这告诉我测试 运行 没有创建报告,因为非零退出代码停止了 Docker 构建步骤退出。

解决方案

我最终延迟了退出代码,以便带有测试标签的容器完成,从而可用于下一步提取报告文件。

RUN npm run test -- --reporters=default --reporters=jest-junit --coverage -- 
watchAll=false; \
echo $? > /npm.exitcode;

# if the npm command failed - fail the build here so that we can get the 
test-report files regardless of exit code
RUN exit $(cat /npm.exitcode)

我还在复制测试结果步骤和发布代码覆盖步骤中添加了 condition: succeededOrFailed(),这样即使构建步骤“失败”,它们也总是 运行。

您可以在 docker 步骤上设置 continueOnError 字段,以启用 运行 的后续步骤。但是,通过这种方式,您的构建以状态 SucceededWithIssues 结束。如果这对你来说没问题,那么一切都完成了。如果不是,您可以在 Agent.JobStatus 条件下放在最后一步,例如

- pwsh: exit 1
  condition eq(variables['Agent.JobStatus'], 'SucceededWithIssues')

构建失败。

您可以尝试以下链接中的解决方法:

https://github.com/MicrosoftDocs/azure-devops-docs/issues/2183 https://github.com/microsoft/vstest/issues/1848

尝试将“exit 0”添加到此行的末尾,如下所示:RUN dotnet test MyProject.Tests.csproj -c Release --logger "trx;LogFileName=testresults.trx"; exit 0