Git钩子脚本如何运行单元测试

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何运行单元测试

  1. 常用的Git钩子类型
  2. 基础示例:pre-commit 钩子
  3. 进阶:限制测试范围(性能优化)
  4. 使用工具管理钩子
  5. 最佳实践
  6. 完整的生产环境示例
  7. 注意事项

Git钩子脚本运行单元测试是实现持续集成和代码质量保证的有效方式,以下是详细的操作指南:

常用的Git钩子类型

适合运行测试的钩子

钩子名称 触发时机 用途
pre-commit 执行git commit 阻止提交到有失败测试的代码
pre-push 执行git push 阻止推送有失败测试的代码
commit-msg 提交消息编辑后 验证提交信息格式

基础示例:pre-commit 钩子

创建钩子文件

# 进入项目根目录的 .git/hooks 目录
cd .git/hooks
# 创建 pre-commit 钩子(去除默认的 .sample 后缀)
touch pre-commit
chmod +x pre-commit

Python项目的pre-commit钩子

#!/bin/bash
# .git/hooks/pre-commit
echo "🚀 运行单元测试..."
# 保存当前暂存的文件列表
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
if [ -z "$STAGED_FILES" ]; then
    echo "✅ 没有需要测试的Python文件"
    exit 0
fi
# 运行单元测试(仅测试被修改的文件)
python -m pytest $STAGED_FILES -v
if [ $? -ne 0 ]; then
    echo "❌ 测试失败,提交被阻止"
    exit 1
fi
echo "✅ 所有测试通过"
exit 0

JavaScript/TypeScript项目的pre-commit钩子

#!/bin/bash
# .git/hooks/pre-commit
echo "🏃 运行单元测试..."
# 运行所有测试
npm test
if [ $? -ne 0 ]; then
    echo "❌ 测试失败,提交被阻止"
    exit 1
fi
# 或者在lint-staged模式下只测试修改的文件
# npx jest --bail --findRelatedTests $(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(js|ts|jsx|tsx)$')
echo "✅ 所有测试通过"
exit 0

进阶:限制测试范围(性能优化)

仅测试修改的文件

#!/bin/bash
# 更高效的pre-commit钩子
function run_tests_for_staged() {
    local staged_files=$(git diff --cached --name-only --diff-filter=ACMR)
    if [ -z "$staged_files" ]; then
        echo "没有暂存的文件"
        exit 0
    fi
    # 根据项目类型选择测试工具
    if [ -f "pytest.ini" ] || [ -f "setup.cfg" ]; then
        echo "🔍 检测到Python项目"
        python -m pytest $(echo "$staged_files" | grep '\.py$') -v --tb=short
    elif [ -f "package.json" ]; then
        echo "🔍 检测到Node.js项目"
        npx jest --bail --findRelatedTests $(echo "$staged_files" | grep -E '\.(js|ts|jsx|tsx)$')
    else
        echo "未知项目类型,运行所有测试"
        npm test || python -m pytest
    fi
}
run_tests_for_staged
if [ $? -ne 0 ]; then
    echo "❌ 测试失败"
    exit 1
fi

使用工具管理钩子

推荐使用工具来管理钩子,避免手动操作:

使用 Husky (JavaScript/TypeScript)

# 安装 husky
npm install husky --save-dev
# 初始化 husky
npx husky install
# 创建 pre-commit 钩子
npx husky add .husky/pre-commit "npm test"
# .husky/pre-commit 文件内容
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm test

使用 pre-commit (Python/多语言)

# 安装 pre-commit
pip install pre-commit
# 创建 .pre-commit-config.yaml
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: local
  hooks:
  - id: pytest
    name: pytest
    entry: pytest
    language: system
    types: [python]
    pass_filenames: false
    always_run: true
    args: ['-v', '--tb=short']
EOF
# 安装钩子
pre-commit install

最佳实践

速度优化

#!/bin/bash
# 优化后的 pre-commit 钩子
# 1. 并行执行测试(如果支持)
function run_tests_parallel() {
    echo "Running tests in parallel..."
    pytest -n auto -v &
    TEST_PID=$!
    wait $TEST_PID
}
# 2. 缓存测试结果
pytest --cache-clear --last-failed
# 3. 只测试受影响的模块
git diff --cached --name-only | grep '\.py$' | xargs pytest -v

跳过测试的特殊情况

#!/bin/bash
# 允许带参数跳过测试
SKIP_TESTS=$(git log -1 --format=%B | grep -c "\[skip-tests\]")
if [ "$SKIP_TESTS" -gt 0 ]; then
    echo "⏭️ 跳过测试(commit message包含 [skip-tests])"
    exit 0
fi
# 或者通过环境变量
if [ "$SKIP_GIT_HOOKS" = "true" ]; then
    echo "⏭️ 跳过测试(环境变量 SKIP_GIT_HOOKS=true)"
    exit 0
fi
# 正常运行测试
npm test

完整的生产环境示例

#!/bin/bash
# .git/hooks/pre-commit - 生产环境版本
set -euo pipefail
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}🏃 启动预提交检查...${NC}"
# 1. 语法检查
echo -e "${YELLOW}📝 检查代码语法...${NC}"
if [ -f "package.json" ]; then
    npx eslint --quiet .
elif [ -f "setup.cfg" ]; then
    python -m py_compile $(git diff --cached --name-only --diff-filter=ACMR | grep '\.py$')
fi
# 2. 运行单元测试
echo -e "${YELLOW}🧪 运行单元测试...${NC}"
if [ -f "package.json" ]; then
    npm test -- --bail --silent
elif [ -f "pytest.ini" ] || [ -f "setup.cfg" ]; then
    python -m pytest -v --tb=short --disable-warnings -q
fi
if [ $? -ne 0 ]; then
    echo -e "${RED}❌ 测试失败,提交被阻止${NC}"
    echo -e "${YELLOW}💡 提示: 如果需要跳过测试,使用 'git commit --no-verify'${NC}"
    exit 1
fi
echo -e "${GREEN}✅ 所有检查通过,可以提交${NC}"
exit 0

注意事项

  1. 性能影响:测试运行会增加提交时间,建议只运行必要的测试
  2. 依赖管理:确保测试环境在钩子中可用(如虚拟环境、node_modules)
  3. 跨平台兼容:注意路径分隔符和命令的兼容性
  4. 错误处理:提供清晰的错误信息和跳过选项
  5. 版本控制:将钩子脚本纳入项目仓库(非.git/hooks目录,而是使用工具管理)

使用Git钩子运行单元测试可以显著提高代码质量,但需要平衡速度和覆盖范围。

抱歉,评论功能暂时关闭!