Bash和测试驱动开发 [英] Bash and Test-Driven Development

查看:117
本文介绍了Bash和测试驱动开发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当不是在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的好方法,或者我应该放弃,把我的努力在其他地方?


解决方案

因此​​,这里是我学到了什么:


  1. 有没有这么多,Bash是不适合TDD(虽然有些
    其他语言浮现在脑海中的是一个更适合),但
    该猛砸用于(安装,系统的典型任务
    配置),这是很难编写测试,并在
    特别难以安装测试。


  2. 在猛砸可怜的数据结构支持,使得它很难分开
    从副作用逻辑,确实有一点一般逻辑
    在的bash脚本。这使得它难以突破脚本到
    可测试块。有一些可以被测试的功能,但
    这是例外,而不是规则。


  3. 功能是一件好事(TM),但它们只能走这么远。<​​/ p>


  4. 嵌套函数可以更好,但他们也是有限的。


  5. 在这一天结束时,与主要的精力有些报道可能
    获得,但它会测试code的少有趣的部分,
    并且将保持大部分的测试作为一个好(或坏)古老的手工
    测试。


元:我决定回答(接受)我自己的问题,因为我无法<一之间进行选择href=\"http://stackoverflow.com/questions/1315624/bash-and-test-driven-development/1315718#1315718\">Sinan Ünür的(投票上)和<一个href=\"http://stackoverflow.com/questions/1315624/bash-and-test-driven-development/1321991#1321991\">mouviciel's (投票了)回答说,在这里同样有用和有见地的。我想说明<一个href=\"http://stackoverflow.com/questions/1315624/bash-and-test-driven-development/1315627#1315627\">Stefano博里尼的答案,这虽然不是IM pressed我开始,我随着时间的推移学会了AP preciate它。也是他的<一个href=\"http://stackoverflow.com/questions/78497/design-patterns-or-best-practices-for-shell-scripts/739034#739034\">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
baz

add_to_file.after:

bar
baz
foo
qux

And 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:

  1. 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.

  2. 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.

  3. Function are a good thing (tm), but they can only go so far.

  4. Nested functions can be even better, but they are also limited.

  5. 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和测试驱动开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆