当不是在bash一个平凡的剧本创作更多,我常常在想如何让code测试。
它通常是硬写对于bash code审核,由于这样的事实,这是低上取一个值,并返回值的函数,而高于该检查和设置的一些方面在环境中的功能,修改文件系统中,调用一个程序,等等 - 依赖于环境或有副作用的功能。因此,设置和测试code变得比code他们测试更加复杂。
例如,考虑一个简单的功能测试:
函数add_to_file(){ 当地F = $ 1 猫>> $ F 排序-u $ F -o $ F}测试code此功能可能包括:
add_to_file.before:
富酒吧巴兹add_to_file.after:
酒吧巴兹富qux和测试code:
函数test_add_to_file(){ CP add_to_file {之前,TMP} add_to_file add_to_file.tmp 。CMP add_to_file {TMP,之后}&放大器;&安培;回声通||回声失败 RM add_to_file.tmp}下面5行code是由测试code的6线和7号线的数据进行测试。
现在考虑一个稍微复杂的情况:
函数分布(){ 本地文件= $ 1;转移 本地主机=($ @) 主机在$ {主机[@]};做 rsync的-ae SSH $文件$主持人:$文件 DONE}我甚至不能说怎么开始写一个测试...
那么,有没有做在的bash脚本TDD的好方法,或者我应该放弃,把我的努力在其他地方?
解决方案因此,这里是我学到了什么:
有没有这么多,Bash是不适合TDD(虽然有些其他语言浮现在脑海中的是一个更适合),但该猛砸用于(安装,系统的典型任务配置),这是很难编写测试,并在特别难以安装测试。
在猛砸可怜的数据结构支持,使得它很难分开从副作用逻辑,确实有一点一般逻辑在的bash脚本。这使得它难以突破脚本到可测试块。有一些可以被测试的功能,但这是例外,而不是规则。
功能是一件好事(TM),但它们只能走这么远。
嵌套函数可以更好,但他们也是有限的。
在这一天结束时,与主要的精力有些报道可能获得,但它会测试code的少有趣的部分,并且将保持大部分的测试作为一个好(或坏)古老的手工测试。
元:我决定回答(接受)我自己的问题,因为我无法Sinan Ünür的(投票上)和mouviciel's (投票了)回答说,在这里同样有用和有见地的。我想说明Stefano博里尼的答案,这虽然不是IM pressed我开始,我随着时间的推移学会了AP preciate它。也是他的design图案或最佳实践的shell脚本回答(最多投票)项以上是有益的。
When writing more than a trivial script in bash, I often wonder how to make the code testable.
It is typically hard to write tests for bash code, due to the fact that it is low on functions that take a value and return a value, and high on functions that check and set some aspect in the environment, modify the file-system, invoke a program, etc. - functions that depend on the environment or have side effects. Thus the setup and test code become much more complicated than the code they test.
For example, consider a simple function to test:
function add_to_file() { local f=$1 cat >> $f sort -u $f -o $f }Test code for this function might consist of:
add_to_file.before:
foo bar bazadd_to_file.after:
bar baz foo quxAnd test code:
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 }Here 5 lines of code are tested by 6 lines of test code and 7 lines of data.
Now consider a slightly more complicated case:
function distribute() { local file=$1 ; shift local hosts=( "$@" ) for host in "${hosts[@]}" ; do rsync -ae ssh $file $host:$file done }I can't even say how to start write a test for that...
So, is there a good way to do TDD in bash scripts, or should I give up and put my efforts elsewhere?
解决方案So here is what I learned:
It is not so much that Bash is not suitable for TDD (although some other languages come to mind that are a better fit), but the typical tasks that Bash is used for (Installation, System configuration), that are hard to write tests for, and in particularly hard to setup the test.
The poor data structure support in Bash makes it hard to separate logic from side-effect, and indeed there is typically little logic in Bash scripts. That makes it hard to break scripts into testable chunks. There are some functions that can be tested, but that is the exception, not the rule.
Function are a good thing (tm), but they can only go so far.
Nested functions can be even better, but they are also limited.
At the end of the day, with major effort some coverage can be obtained, but it will test the less interesting part of the code, and will keep the bulk of the testing as a good (or bad) old manual testing.
Meta: I decided to answer (and accept) my own question, because I was unable to choose between Sinan Ünür's (voted up) and mouviciel's (voted up) answers that where equally useful and insightful. I want to note Stefano Borini's answer, that although not impressed me initially, I learned to appreciate it over time. Also his design patterns or best practices for shell scripts answer (voted up) referred above was useful.
更多推荐
Bash和测试驱动开发
发布评论