在现实世界中的脚本通常被用来调用诸如实用程序find,tar,cpio,grep,sed,rsync,date等含有很多选择一些比较复杂的命令行.有时构造和使用正则表达式或通配符模式.
一个例子:这通常是由cron中定期调用的shell脚本必须从一台计算机的一些巨大的目录树镜像到另一个使用该实用程序的任务rsync的.应该从镜像过程中排除几种类型的文件和目录:
#!/usr/bin/env bash
...
function mirror() {
...
COMMAND="rsync -aH$VERBOSE$DRY $PROGRESS $DELETE $OTHER_OPTIONS \
$EXCLUDE_OPTIONS $SOURCE_HOST:$DIRECTORY $TARGET"
...
if eval $COMMAND
then ...
else ...
fi
...
}
...
Run Code Online (Sandbox Code Playgroud)
正如Michael Feathers在其着名的书"有效地使用遗留代码"中所写,一个好的单元测试运行得非常快,并且不会触及网络,文件系统或打开任何数据库.
根据Michael Feathers的建议,这里使用的技术是:依赖注入.这里要替换的对象是实用程序rsync.
我的第一个想法:在我的shell脚本测试框架(我使用bats)中,我操作$PATH的方式是找到一个模型 rsync而不是真正的rsync实用程序.此模型对象可以检查提供的命令行参数和选项.与此测试脚本部分中使用的其他实用程序类似.
我之前在脚本编写方面遇到实际问题的经验通常是由文件或目录名中的特殊字符引起的错误,引用或编码问题,ssh密钥丢失,权限错误等等.这种类型的错误将逃脱这种单元测试技术.(我知道:对于其中一些问题,单元测试根本不是治愈方法).
另一个缺点是为复杂的实用程序编写一个类似的模型 …
我正在编写一个BATS(Bash自动化测试系统)脚本,我想要的是一个在所有测试中保持不变的变量.例如:
#!/usr/bin/env bats
# Generate random port number
port_num=$(shuf -i 2000-65000 -n 1)
@test "Test number one" {
a = $port_num
}
@test "Test number two" {
b = $port_num
}
Run Code Online (Sandbox Code Playgroud)
评估时,a和b应该相等.但这不起作用,因为(根据文档)在每次测试运行后评估整个文件.这意味着$ port_num在测试之间重新生成.我是否有办法/地方存储将在所有测试中保留的变量?
我运行了一些bats脚本来测试某些功能,如何在脚本中回显 bats 文件名?
我的蝙蝠脚本看起来像:
#!/usr/bin/env bats
load test_helper
echo $BATS_TEST_FILENAME
@test "run cloned mission" {
blah blah blah
}
Run Code Online (Sandbox Code Playgroud)
为了使我的报告显示为:
? run cloned mission
? run cloned mission
? addition using bc
---- TEST NAME IS xxx
? run cloned mission
? run cloned mission
? addition using bc
---- TEST NAME IS yyy
? run cloned mission
? run cloned mission
? addition using bc
Run Code Online (Sandbox Code Playgroud)
但得到了错误
2: syntax error:
operand expected (error token is ".bats
2")
Run Code Online (Sandbox Code Playgroud)
正确的做法是什么?我不想更改它的集合名称只是为了在不同测试之间回显文件名。 …
我正在尝试使用蝙蝠在我正在研究的项目中测试一些关键的shell脚本。我希望能够模拟脚本,以便断言一个脚本在给定情况下使用正确的参数调用了另一个脚本。该蝙蝠-模拟图书馆好像它应该做的伎俩,但它尚未在所有记录在案。
我曾尝试查看bats-mock代码和其他人创建的一些测试帮助程序脚本(如本示例),但是不幸的是,我对bash不够满意,无法推断出如何正确使用bats-mock库。
如何使用bats-mock库来模拟脚本并断言对模拟的调用?
我有一个要获取的实用程序脚本,其中包含两个提示用户输入的函数;anykey和yesno。
如何测试提示?提示文本不显示在 中$output。
另外,如何强制 while 循环yesno从测试中跳出 while 循环?
function anykey() { read -n 1 -r -s -p "${1:-Press any key to continue ...}"; }
function yesno() {
local -u yn
while true; do
# shellcheck disable=SC2162
read -N1 -p "${1:-Yes or no?} " yn
case $yn in
Y | N)
printf '%s' "$yn"
return
;;
Q)
warn 'Exiting...'
exit 1
;;
*)
warn 'Please enter a Y or a N'
;;
esac …Run Code Online (Sandbox Code Playgroud)