pbl_evidence/scripts/run_tests.sh
2026-09-23 00:03:13 +08:00

97 lines
4.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# =====================================================================
# pbl_evidence 测试运行器(发现项 DISC.2)
#
# 一条命令跑通离线单测,**不需要手工注入 PYTHONPATH**:
# bash scripts/run_tests.sh # 等价 python3 -m pytest tests/test_m5a_idempotency.py -v
# bash scripts/run_tests.sh tests/test_m5a_idempotency.py -v
# bash scripts/run_tests.sh --log /tmp/m5a-pytest.log
# PBL_EVIDENCE_TEST_DB=1 bash scripts/run_tests.sh # 打开真实双次采集用例(需测试库)
# PBL_EVIDENCE_TEST_DB=1 PBL_EVIDENCE_TEST_TENANT=m5a-demo bash scripts/run_tests.sh
#
# 想在当前 shell 里**原样**敲 `python3 -m pytest ...`(任务要求的字面命令):
# source scripts/activate_test_env.sh && python3 -m pytest tests/test_m5a_idempotency.py -v
#
# 解释器解析顺序(第一个「能 import pytest」的胜出):
# ① $PBL_EVIDENCE_TEST_PYTHON —— 显式指定(CI 用宿主 venv 时走这条)
# ② 宿主 python3 —— 若已 pip install pytest / -e .[test](正规长期方案)
# ③ 模块测试 venv .venv-test/bin/python —— 缺则自动调 scripts/setup_test_env.sh 引导
# 全部不可用 → exit 3 并打印可执行的修复命令(不静默跳过、不假绿)。
#
# 为什么不再用 PYTHONPATH=<workspace>/.pylibs:那是工作空间私有的临时目录,
# 换机器/换角色即失效,且把「环境缺依赖」伪装成「测试通过」,属 DISC.2 根因。
# =====================================================================
set -euo pipefail
MODULE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VENV="${PBL_EVIDENCE_TEST_VENV:-${MODULE_ROOT}/.venv-test}"
DEFAULT_TARGET="tests/test_m5a_idempotency.py -v"
log() { echo "[run_tests] $*"; }
die() { echo "[run_tests][FATAL] $*" >&2; exit "${2:-1}"; }
has_pytest() {
local py="$1"
[ -x "${py}" ] || return 1
"${py}" -c 'import pytest' >/dev/null 2>&1
}
cd "${MODULE_ROOT}"
# ---- 仓库卫生自检(QC #1 回归防线,不阻断测试,只打印)----
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
_hyg="$(git check-ignore -q "${VENV#${MODULE_ROOT}/}" && echo ignored || echo NOT-ignored)"
_trk="$(git ls-files "${VENV#${MODULE_ROOT}/}" | wc -l | tr -d ' ')"
log "仓库卫生: .gitignore=${_hyg} tracked_in_venv=${_trk}(期望 ignored / 0)"
[ "${_hyg}" = "ignored" ] || log "[WARN] venv 落点未被 .gitignore 忽略,会把依赖目录提交进版本库"
[ "${_trk}" = "0" ] || log "[WARN] venv 内有 ${_trk} 个文件仍被版本跟踪,执行 git rm -r --cached '${VENV#${MODULE_ROOT}/}'"
fi
# ---- 解析解释器 ----
PY=""
for cand in "${PBL_EVIDENCE_TEST_PYTHON:-}" "$(command -v python3 || true)" "${VENV}/bin/python"; do
[ -n "${cand}" ] || continue
if has_pytest "${cand}"; then
PY="${cand}"
break
fi
done
if [ -z "${PY}" ]; then
log "宿主 python3 与测试 venv 均无 pytest,引导测试环境(scripts/setup_test_env.sh)"
bash "${MODULE_ROOT}/scripts/setup_test_env.sh" || die "测试环境引导失败,见上方日志" 3
PY="${VENV}/bin/python"
has_pytest "${PY}" || die "引导后仍无法 import pytest(${PY})" 3
fi
log "python = ${PY} ($("${PY}" -V 2>&1))"
log "pytest = $("${PY}" -m pytest --version 2>&1 | head -1)"
log "cwd = ${MODULE_ROOT}"
[ "${PBL_EVIDENCE_TEST_DB:-}" = "" ] && \
log "DB 开关 = 未设置(真实双次采集用例 test_double_collect_is_idempotent_with_db 预期 SKIPPED)" || \
log "DB 开关 = PBL_EVIDENCE_TEST_DB=${PBL_EVIDENCE_TEST_DB} tenant=${PBL_EVIDENCE_TEST_TENANT:-m5a-idem-test}"
# ---- 参数:无参数时用默认目标;--log FILE 把输出同时落盘 ----
LOG=""
ARGS=()
while [ $# -gt 0 ]; do
case "$1" in
--log) LOG="${2:-}"; shift 2 ;;
*) ARGS+=("$1"); shift ;;
esac
done
[ ${#ARGS[@]} -gt 0 ] || ARGS=(${DEFAULT_TARGET})
if [ -n "${LOG}" ]; then
mkdir -p "$(dirname "${LOG}")"
set +e
"${PY}" -m pytest "${ARGS[@]}" 2>&1 | tee "${LOG}"
RC=${PIPESTATUS[0]}
set -e
echo "# RC=${RC}" >> "${LOG}"
else
"${PY}" -m pytest "${ARGS[@]}"
RC=$?
fi
exit ${RC}