在使用bash编写不仅仅是一个琐碎的脚本时,我经常想知道如何使代码可测试。
通常很难为bash代码编写测试,因为使用值并返回值的函数很低,而在环境中检查和设置某些方面、修改文件系统、调用程序等的函数都很低,这些函数依赖于环境或有副作用。因此,设置和测试代码比它们测试的代码复杂得多。
例如,考虑一个要测试的简单函数:
function add_to_file() {
local f=$1
cat >> $f
sort -u $f -o $f
}此函数的测试代码可能包括:
add_to_file.before:
foo
bar
bazadd_to_file.after:
bar
baz
foo
qux和测试代码:
function test_add_to_file() {
cp add_to_file.{before,tmp}
add_to_file add_to_file.tmp
cmp add_to_file.{tmp,after} && echo pass || echo fail
rm add_to_file.tmp
}这里,5行代码由6行测试代码和7行数据进行测试。
现在考虑一个稍微复杂一些的案例:
function distribute() {
local file=$1 ; shift
local hosts=( "$@" )
for host in "${hosts[@]}" ; do
rsync -ae ssh $file $host:$file
done
}我甚至说不出该怎么开始写测试.
那么,是否有一种在bash脚本中进行TDD的好方法,或者我应该放弃并将我的努力放在其他地方呢?
发布于 2009-09-12 13:48:11
以下是我学到的:
Meta:我决定回答(并接受)我自己的问题,因为我无法在同样有用和有洞察力的西南纽尔氏 ( up)和穆维西尔氏 ( up)之间做出选择。我想注意到斯特凡诺·博里尼氏的回答,虽然一开始并没有给我留下深刻的印象,但随着时间的推移,我学会了欣赏它。此外,上面提到的他的shell脚本的设计模式或最佳实践 (投票结果)也很有用。
发布于 2009-08-22 10:36:46
如果您在编写代码的同时进行测试,请尝试将其提高到除参数之外不使用任何其他任何东西且不修改环境的函数上。也就是说,如果您的函数同样可以在子subshell中运行,那么它将很容易测试。它需要一些参数并输出一些东西到stdout,或者到一个文件,或者它在系统上做了一些事情,但是调用者没有感觉到副作用。
是的,您最终将传递一些可能是全局的WORKING_DIR变量,但这与跟踪每个函数读取和修改什么的任务相比,会带来很小的不便。启用单元测试也是一种免费的奖励。
尽量减少需要输出的情况。轻微的子外壳滥用将有助于保持良好的分离(以牺牲性能为代价)。
不是调用函数的线性结构,而是设置一些环境,然后调用其他环境,几乎都在一个级别上,尝试使用深度调用树,返回的数据最少。在巴什返回东西是不方便的,如果你采取自我强制禁欲,从全球范围内.
https://stackoverflow.com/questions/1315624
复制相似问题