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

GitLab Runner中sed命令执行异常 无法正确提取测试覆盖率

GitLab Runner环境下npm测试覆盖率提取脚本失效修复

问题现象

编写脚本执行npm run test并捕获测试覆盖率数值,目标是提取输出中总覆盖率的36.95数值,作为GitLab Job的输出内容。
本地环境执行脚本可正常返回提取到的36.95,经确认使用的GitLab Runner为GNU版本,但在Runner上运行时会直接返回npm run test的原始输出,无法完成数值提取,需要适配当前Runner环境。

初始失效脚本如下:

RES=$(npm test -- --coverage --watchAll=false)
TOTAL=$(sed -E 's/^.* All files \| ([^ ]+) \| .*$/\1/' <<< $RES)
echo "Current test coverage is : " $TOTAL

初步判断here-string(<<<)语法与Runner运行环境不兼容,也不排除脚本本身存在编写问题。当前使用的GitLab Pipeline配置如下:

test:
  stage: test
  image: node:16.13.1
  before_script:
    - npm i
    - npx node -v
    - npx npm -v
  script:
    - echo "running test coverage"
    - bash test.sh

其中test.sh文件内容即为上述用于提取测试覆盖率的脚本。

根因分析

  • Jest的覆盖率报告默认输出到stderr而非stdout,原脚本仅捕获stdout内容,在容器环境下没有拿到覆盖率表格数据,自然无法提取数值,本地环境能跑是因为本地npm/shell配置默认将stderr重定向到了stdout
  • here-string(<<<)是Bash专属语法,部分精简版容器镜像内的Bash实现存在兼容问题,且如果脚本缺少明确shebang头,存在被POSIX sh(node镜像默认是dash)解析的可能,会直接语法失效
  • 原sed匹配规则写死了空格数量,不同终端宽度下jest输出的表格对齐空格数变化,会导致匹配失败

修复方案

修改test.sh内容为以下版本即可:

#!/bin/bash
# 同时捕获stdout、stderr的所有输出
RES=$(npm test -- --coverage --watchAll=false 2>&1)
# 用POSIX标准管道语法替换here-string,适配所有shell环境
# 优化正则匹配规则,兼容任意数量的对齐空白字符
TOTAL=$(echo "$RES" | sed -E 's/^.*All files[[:space:]]+\|[[:space:]]+([0-9]+\.[0-9]+)[[:space:]]+\|.*$/\1/')
echo "Current test coverage is : $TOTAL"

修复点说明:

  • 脚本开头加#!/bin/bash shebang头,明确指定解释器,避免被其他shell解析
  • 重定向配置加2>&1,将stderr输出合并到stdout,确保覆盖率表格内容能被完整捕获到变量中
  • 用管道写法替换here-string语法,兼容所有POSIX标准shell,不存在版本兼容问题
  • 优化sed匹配规则,用[[:space:]]+匹配任意数量的对齐空白字符,适配不同输出宽度下的表格格式

原有GitLab Pipeline配置不需要额外修改,保持原有逻辑即可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:48:20