#!/usr/bin/env bash # 跑全仓库的单元测试(纯逻辑:不需要硬件、不需要 Gazebo、不发运动指令)。 # # 为什么要有这个脚本,而不是让人手敲 pytest # ---------------------------------------- # 测试都按**包名**导入(arm_application.* / arm_sim_gazebo.* / arm_kinematics.*), # 所以 PYTHONPATH 必须同时包含 src/ 下所有包目录。手敲很容易漏一个: # 漏了 src/arm_kinematics,`from arm_application.pipeline_node import ...` 会在 # 收集阶段就 ModuleNotFoundError —— 现象是"测试跑了 0 个 / 1 个 error", # 很容易被读成"测试环境坏了",而不是"少了一个路径"。 # # 用法: # bash scripts/run_unit_tests.sh # 全部 # bash scripts/run_unit_tests.sh -k gauge # 只跑名字带 gauge 的 # bash scripts/run_unit_tests.sh src/arm_sim_gazebo/test/test_sim_scene.py -x # # 环境:真机 conda 环境或仿真环境都能跑;缺可选依赖的用例自己会 skip #(例如 onnx/ultralytics 只在真机环境有 —— 见各测试里的 pytest.importorskip)。 set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PY="${PYTHON:-python3}" # 把所有 src/* 目录挂到 PYTHONPATH 最前面(包名不冲突,顺序无关)。 paths=() for d in "${ROOT}"/src/*/; do paths+=("${d%/}") done export PYTHONPATH="$(IFS=:; echo "${paths[*]}")${PYTHONPATH:+:${PYTHONPATH}}" test_dirs=() for d in "${ROOT}"/src/*/test; do [ -d "$d" ] && test_dirs+=("$d") done if [ "${#test_dirs[@]}" -eq 0 ]; then echo "没有找到任何测试目录(src/*/test)—— 仓库不完整?" >&2 exit 1 fi cd "${ROOT}" if [ "$#" -gt 0 ]; then exec "${PY}" -m pytest "${test_dirs[@]}" -q "$@" fi exec "${PY}" -m pytest "${test_dirs[@]}" -q