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

如何实现测试脚本失败且输出含特定文本时自动多次重跑?

解决不稳定测试的自动重跑问题

需求背景

我们有部分不稳定测试偶尔失败,正在排查根因。这类失败的测试输出中固定出现文本The current node list is empty。需要实现:

  • 测试失败且输出包含该文本时,自动重跑多次
  • 测试失败但输出不含该文本,直接标记失败

原方案问题

尝试的重复执行命令虽然能在匹配文本出现时重跑,但即使测试失败也会被判定为成功——原因是ack --passthru在找到匹配文本时返回0,覆盖了pest测试的退出码,导致整个管道的退出码被ack的结果替换。

原尝试的命令(注意最后一行缺少闭合引号):

docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty" &&
        docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml | ack --passthru --color "The current node list is empty

解决方案

方法1:封装测试逻辑,精准控制退出码

把单次测试逻辑封装成函数,单独捕获测试的退出码和输出,再判断是否需要重跑:

# 封装单次测试逻辑
run_test() {
  # 执行测试,保存输出到临时文件,捕获原退出码
  docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml > test_output.txt 2>&1
  local test_exit_code=$?
  
  # 输出内容到终端,同时用ack高亮目标文本
  cat test_output.txt | ack --passthru --color "The current node list is empty"
  
  # 判定逻辑:测试失败且含目标文本时返回特殊码(100),否则返回原退出码
  if [ $test_exit_code -ne 0 ]; then
    if grep -q "The current node list is empty" test_output.txt; then
      return 100
    fi
  fi
  return $test_exit_code
}

# 循环执行测试,最多重跑10次
max_retries=10
retry_count=0
final_exit_code=0

while [ $retry_count -lt $max_retries ]; do
  run_test
  final_exit_code=$?
  
  # 不是需要重跑的情况,直接退出循环
  if [ $final_exit_code -ne 100 ]; then
    break
  fi
  
  retry_count=$((retry_count + 1))
  echo "检测到目标错误,开始第 $retry_count 次重跑..."
done

# 返回最终退出码
exit $final_exit_code

方法2:用grep替代ack实现高亮+逻辑控制

如果不想依赖ack,用grep也能实现文本高亮和退出码控制:

run_test() {
  # 捕获测试输出和退出码
  local test_output
  test_output=$(docker compose --project-directory ./app --env-file ./.env exec php vendor/bin/pest --coverage-clover=clover.xml 2>&1)
  local test_exit_code=$?
  
  # 高亮输出目标文本(grep的-E参数匹配所有行+目标文本)
  echo "$test_output" | grep --color=always -E "(The current node list is empty|.*)"
  
  # 重跑判定逻辑和方法1一致
  if [ $test_exit_code -ne 0 ]; then
    if echo "$test_output" | grep -q "The current node list is empty"; then
      return 100
    fi
  fi
  return $test_exit_code
}

# 循环调用部分和方法1完全相同
max_retries=10
retry_count=0
final_exit_code=0

while [ $retry_count -lt $max_retries ]; do
  run_test
  final_exit_code=$?
  
  if [ $final_exit_code -ne 100 ]; then
    break
  fi
  
  retry_count=$((retry_count + 1))
  echo "检测到目标错误,开始第 $retry_count 次重跑..."
done

exit $final_exit_code

核心逻辑说明

  • 单独捕获测试命令的退出码,避免被后续文本处理命令的退出码覆盖
  • 用特殊退出码(如100)标记「需要重跑」的场景,和「真正测试失败」的场景区分开
  • 循环逻辑只在收到「需要重跑」的退出码时才执行下一次测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:11:00