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

Node.js Docker构建:如何在YAML/Dockerfile中添加测试用例

Node.js项目Docker构建中测试任务的实现方案

方案1:在Dockerfile中嵌入测试(构建阶段验证)

利用Docker多阶段构建,在编译代码前执行测试用例,测试失败则直接终止镜像构建,避免不合格镜像流入后续环节。

修改后的Dockerfile示例:

FROM node:20.8.1 as node
WORKDIR /app
RUN npm cache clean --force
COPY package*.json ./
RUN npm install
COPY . .
# 新增测试步骤,测试失败则构建终止
RUN npm run test
RUN npm run build --prod

#Stage: 2
FROM nginx:alpine
COPY --from=node /app/dist/it-planning /usr/share/nginx/html

说明:将npm run test放在npm run build之前,确保只有测试通过的代码才会被编译打包。默认npm install会安装devDependencies,若你的测试依赖该目录下的包,无需额外调整;如果之前用了npm install --production,则要去掉该参数。

方案2:在Azure DevOps流水线(YAML)中添加独立测试步骤(构建前验证)

在Docker构建任务之前,直接在流水线Agent上安装Node环境并执行测试,无需修改Dockerfile,测试结果可直接在流水线日志中展示,方便快速定位问题。

修改后的YAML流水线示例:

trigger:
  branches:
    include:
    - main
resources:
  repositories:
  - repository: self
variables:
  dockerRegistryServiceConnection: 'xxxxxx9f-xxxxx-xxxxx-xxxx'
  ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
      imageRepository: 'jui-dev'
      webAppName: 'itdev'
  containerRegistry: 'jmrtvg.azurecr.io'
  dockerfilePath: '$(Build.SourcesDirectory)/dockerfile'
  tag: '$(Build.BuildId)'
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    # 新增:安装指定版本Node并执行测试
    - task: NodeTool@0
      inputs:
        versionSpec: '20.x'
      displayName: 'Install Node.js'
    - script: |
        npm cache clean --force
        npm install
        npm run test
      displayName: 'Run unit tests'
    # 原有的Docker构建推送任务
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: 
          $(tag)
    - task: AzureRmWebAppDeployment@4
      inputs:
        ConnectionType: 'AzureRM'
        azureSubscription: JMsDe
        appType: 'webAppContainer'
        WebAppName: $(webAppName)
        DockerNamespace: 'jM.azurecr.io'
        DockerRepository: $(imageRepository)
        DockerImageTag: '$(tag)'

说明:通过NodeTool安装与项目匹配的Node版本,执行测试命令后,若测试失败流水线会直接中断,不会进入Docker构建环节。

方案3:构建镜像后启动容器测试(镜像运行状态验证)

先构建镜像,再基于该镜像启动临时容器,验证镜像内服务的运行状态(如接口可用性、服务启动情况),测试通过后再推送镜像并部署。

修改后的YAML流水线示例:

trigger:
  branches:
    include:
    - main
resources:
  repositories:
  - repository: self
variables:
  dockerRegistryServiceConnection: 'xxxxxx9f-xxxxx-xxxxx-xxxx'
  ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
      imageRepository: 'jui-dev'
      webAppName: 'itdev'
  containerRegistry: 'jmrtvg.azurecr.io'
  dockerfilePath: '$(Build.SourcesDirectory)/dockerfile'
  tag: '$(Build.BuildId)'
  vmImageName: 'ubuntu-latest'
  fullImageName: '$(containerRegistry)/$(imageRepository):$(tag)'

stages:
- stage: Build
  displayName: Build and test image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    # 先构建镜像(暂不推送)
    - task: Docker@2
      displayName: Build Docker image
      inputs:
        command: build
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: 
          $(tag)
    # 启动容器执行集成测试
    - script: |
        # 启动容器并暴露端口(根据服务实际端口调整)
        docker run -d -p 8080:80 --name test-container $(fullImageName)
        # 等待服务启动(根据服务启动速度调整等待时间)
        sleep 10
        # 示例:用curl检查服务首页是否正常响应
        curl -f http://localhost:8080 || exit 1
        # 停止并清理测试容器
        docker stop test-container
        docker rm test-container
      displayName: 'Test Docker image runtime status'
    # 测试通过后推送镜像
    - task: Docker@2
      displayName: Push Docker image to registry
      inputs:
        command: push
        repository: $(imageRepository)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: 
          $(tag)
    # 部署任务
    - task: AzureRmWebAppDeployment@4
      inputs:
        ConnectionType: 'AzureRM'
        azureSubscription: JMsDe
        appType: 'webAppContainer'
        WebAppName: $(webAppName)
        DockerNamespace: 'jM.azurecr.io'
        DockerRepository: $(imageRepository)
        DockerImageTag: '$(tag)'

说明:这种方式适合集成测试,验证镜像部署后的服务状态。注意最终镜像(nginx阶段)没有Node环境,无法运行单元测试,仅适合验证服务可用性。

方案选择建议

  • 单元测试优先选方案1或方案2:方案1确保镜像只包含测试通过的代码;方案2在流水线独立执行,日志更直观,无需修改Dockerfile。
  • 集成测试(验证服务运行状态)选方案3,需根据服务实际情况调整测试命令。

内容的提问来源于stack exchange,提问作者Murali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:44:56