Bats-core: Bash自动化测试系统
Bats-core是一个符合TAP标准的Bash测试框架,支持Bash 3.2及以上版本。它提供了一种简单的方法来验证您编写的UNIX程序是否按预期行为运行。
功能特性
- TAP兼容测试输出:生成标准化的测试输出格式
- 简洁的测试语法:使用特殊的Bash语法定义测试用例
- 完整的工具链:包含安装、卸载、版本管理脚本
- 多平台支持:支持各种UNIX系统和架构
- ShellCheck集成:内置代码质量检查工具
- 灵活的安装选项:支持自定义安装路径和库目录
- 版本管理:提供专业的版本发布和更新工具
安装指南
基本安装
# 克隆仓库
git clone https://github.com/bats-core/bats-core.git
cd bats-core
# 安装到系统目录
./install.sh /usr/local
# 或者安装到自定义目录
./install.sh ~/bats
自定义库目录安装
# 指定库目录(如lib64)
./install.sh /usr/local lib64
依赖要求
- Bash 3.2或更高版本
- 标准UNIX工具(install, find, sed等)
- 可选:Ron用于生成手册页
使用说明
创建测试文件
#!/usr/bin/env bats
@test "加法测试 - 使用bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
@test "加法测试 - 使用dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
@test "文件存在性测试" {
run ls /etc/passwd
[ "$status" -eq 0 ]
[ "$output" = "/etc/passwd" ]
}
运行测试
# 运行所有测试
bats test/
# 使用TAP格式输出
bats --tap test/
# 运行单个测试文件
bats my_test.bats
测试项目结构
my_project/
├── src/
│ └── my_script.sh
└── test/
├── unit/
│ └── test_basics.bats
└── integration/
└── test_complex.bats
核心代码
安装脚本核心逻辑
#!/usr/bin/env bash
set -e
BATS_ROOT="${0%/*}"
PREFIX="${1%/}"
LIBDIR="${2:-lib}"
# 参数验证
if [[ -z "$PREFIX" ]]; then
printf '%s\n' \
"usage: $0 <prefix> [base_libdir]" \
" e.g. $0 /usr/local" \
" $0 /usr/local lib64" >&2
exit 1
fi
# 创建目录结构
install -d -m 755 "$PREFIX"/{bin,libexec/bats-core,"${LIBDIR}"/bats-core,share/man/man{1,7}}
# 安装文件
install -m 755 "$BATS_ROOT/bin"/* "$PREFIX/bin"
install -m 755 "$BATS_ROOT/libexec/bats-core"/* "$PREFIX/libexec/bats-core"
install -m 755 "$BATS_ROOT/lib/bats-core"/* "$PREFIX/${LIBDIR}/bats-core"
install -m 644 "$BATS_ROOT/man/bats.1" "$PREFIX/share/man/man1"
install -m 644 "$BATS_ROOT/man/bats.7" "$PREFIX/share/man/man7"
# 更新库目录配置
read -rd '' BATS_EXE_CONTENTS <"$PREFIX/bin/bats" || true
BATS_EXE_CONTENTS=${BATS_EXE_CONTENTS/"BATS_BASE_LIBDIR=lib"/"BATS_BASE_LIBDIR=${LIBDIR}"}
printf "%s" "$BATS_EXE_CONTENTS" >| "$PREFIX/bin/bats"
echo "Installed Bats to $PREFIX/bin/bats"
卸载脚本核心逻辑
#!/usr/bin/env bash
set -e
BATS_ROOT="${0%/*}"
PREFIX="${1%/}"
# 参数检查
if [[ -z "$PREFIX" ]]; then
printf '%s\n' \
"usage: $0 <prefix> [base_libdir]" \
" e.g. $0 /usr/local" \
" $0 /usr/local lib64" >&2
exit 1
fi
# 目录存在性验证
if [[ ! -d "$PREFIX" ]]; then
printf "No valid installation in directory %s.\n" "$PREFIX"
exit 2
fi
# 自动检测库目录
if [ -e "$PREFIX/bin/bats" ]; then
LIBDIR=$(grep -e '^BATS_BASE_LIBDIR=' "$PREFIX/bin/bats")
eval "$LIBDIR"
fi
LIBDIR="${BATS_BASE_LIBDIR:-lib}"
# 文件删除函数
remove_file() {
echo "Removing $1"
rm -f "$1"
}
remove_directory() {
local directory=$1
if [[ -d "$directory" ]]; then
echo "Removing $directory"
rmdir "$directory"
fi
}
# 清理安装的文件
d="$PREFIX/bin"
for elt in "$BATS_ROOT/bin"/*; do
elt=${elt##*/}
remove_file "$d/$elt"
done
echo "Uninstalled Bats from $PREFIX/bin/bats"
版本发布工具
#!/usr/bin/env bash
set -Eeuo pipefail
# 版本信息提取
BATS_VERSION=$(
source <(grep '^export BATS_VERSION=' libexec/bats-core/bats)
echo "${BATS_VERSION}"
)
# 版本更新函数
replace_in_files() {
declare -a FILE_REPLACEMENTS=(
"contrib/rpm/bats.spec,^Version:"
"libexec/bats-core/bats,^export BATS_VERSION="
"package.json,^ \"version\":"
)
for FILE_REPLACEMENT in "${FILE_REPLACEMENTS[@]}"; do
FILE="${FILE_REPLACEMENT/,*/}"
MATCH="${FILE_REPLACEMENT/*,/}"
sed -E -i.bak "/${MATCH}/ { s,${BATS_VERSION},${NEW_BATS_VERSION},g; }" "${FILE}"
rm "${FILE}.bak" || true
git add -f "${FILE}"
done
}
# 更新变更日志
write_changelog() {
local FILE="docs/CHANGELOG.md"
sed -E -i.bak "/## \[Unreleased\]/ a \\\n## [${NEW_BATS_VERSION}] - $(date +%Y-%m-%d)" "${FILE}"
rm "${FILE}.bak" || true
git add -f "${FILE}"
}
ShellCheck代码质量检查
#!/usr/bin/env bash
set -e
# 查找所有Bash相关文件
targets=()
while IFS= read -r -d $'\0'; do
targets+=("$REPLY")
done < <(
find . -type f \( -name \*.bash -o -name \*.sh \) -print0
find . -type f -name '*.bats' -not -name '*_no_shellcheck*' -print0
find libexec -type f -print0
find bin -type f -print0
)
# 执行ShellCheck检查
LC_ALL=C.UTF-8 shellcheck -x "${targets[@]}"
这些核心代码展示了Bats-core项目的完整工具链,包括专业的安装卸载流程、版本管理和代码质量保证机制,体现了项目对测试框架稳定性和可靠性的高度重视。