标签: bats-core

如何编写单元可测试的bash shell代码?

在OOP Universum于,有很多的信息,如何与DESGIN重构代码,使其单元测试友好.但我想知道,如何将这些原则/实践(使模拟更容易等)应用/翻译成shell脚本,这显然是不同的编程.

我必须解决一个非常庞大的代码库; 许多可执行和不可执行的过程,大型函数,大型全局状态,许多环境变量,以及通过重定向/管道和(不必要的)使用外部实用程序的任何地方(不必要的)进程间通信和文件处理.

如何重构shell代码(或在开头设计它),以便能够使用像bats和mocking-plugin这样的框架进行"良好"的自动单元测试?

bash shell unit-testing mocking bats-core

7
推荐指数
1
解决办法
424
查看次数

Shell脚本单元测试:如何模拟复杂的实用程序

我正在对一些遗留的 shell脚本进行单元测试.

在现实世界中的脚本通常被用来调用诸如实用程序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密钥丢失,权限错误等等.这种类型的错误将逃脱这种单元测试技术.(我知道:对于其中一些问题,单元测试根本不是治愈方法).

另一个缺点是为复杂的实用程序编写一个类似的模型 …

bash shell unit-testing bats-core

6
推荐指数
1
解决办法
1009
查看次数

BATS:在所有测试中使变量持久化

我正在编写一个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在测试之间重新生成.我是否有办法/地方存储将在所有测试中保留的变量?

testing bash bats-core

5
推荐指数
1
解决办法
862
查看次数

bats - 我如何在 bats 脚本中回显文件名以进行报告

我运行了一些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)

正确的做法是什么?我不想更改它的集合名称只是为了在不同测试之间回显文件名。 …

bash automation bats-core

3
推荐指数
1
解决办法
1131
查看次数

在Bash测试中如何使用bats-mock断言对模拟脚本的调用

我正在尝试使用蝙蝠在我正在研究的项目中测试一些关键的shell脚本。我希望能够模拟脚本,以便断言一个脚本在给定情况下使用正确的参数调用了另一个脚本。该蝙蝠-模拟图书馆好像它应该做的伎俩,但它尚未在所有记录在案。

我曾尝试查看bats-mock代码和其他人创建的一些测试帮助程序脚本(如本示例),但是不幸的是,我对bash不够满意,无法推断出如何正确使用bats-mock库。

如何使用bats-mock库来模拟脚本并断言对模拟的调用?

bash unit-testing mocking bats-core

2
推荐指数
1
解决办法
870
查看次数

如何使用 bat 测试 `read -p`

我有一个要获取的实用程序脚本,其中包含两个提示用户输入的函数;anykeyyesno

如何测试提示?提示文本不显示在 中$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)

bats-core

2
推荐指数
1
解决办法
826
查看次数

标签 统计

bats-core ×6

bash ×5

unit-testing ×3

mocking ×2

shell ×2

automation ×1

testing ×1