如何在 shell 函数中创建输出以使用 bats 进行单元测试?
How to create output in a shell function for unit testing with bats?
在设置了可以测试某个目录中的 shell 脚本的 bats 测试框架之后,我试图扩展 bats 测试以测试另一个 [=51] 中编写的 shell 函数=] 文件名为 passive_function.sh
.
测试设置
我创建了一个 template repository 来执行 shell 测试。它在文件夹 /test/
中包含一个名为 test_other_shell.bats
的文件,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function.sh." {
run ./src/active_function.sh 9 33
assert_output 42
}
然后我创建了一个名为 main.sh
的文件,内容为:
#!/bin/sh
some_active_function() {
sum=" + " | bc -l
echo "$sum"
}
some_active_function
测试结果
运行 来自终端的蝙蝠测试失败并输出:
✗ running the file in /src/active_function.sh.
(from function `assert_output' in file test/libs/bats-assert/src/assert.bash, line 239,
in test file test/test_active_function.bats, line 8)
`assert_output 42' failed
-- output differs --
expected : 42
actual :
--
功能验证
我通过运行手动验证了这个函数returns 42
:
source ./src/active_function.sh; some_active_function 9 33
来自终端,打印:
42
42
问题
如何编写蝙蝠测试来测试 shell 函数,其中 returns 输入 2 个整数相加?
例如如果我调用 somefunc 3 5
如果函数 returns 8
测试通过,否则失败。
sum=" + " | bc -l
是否不将sum
变量设置为数字的总和:
- 管道意味着 bash 运行 在单独的子 shell 中管道中的每个命令。
- 第一个子 shell
sum
分配了字符串“9 + 33”,并且没有输出
- 第二个子 shell 开始 bc 并向其标准输入发送一个空字符串,因此 bc 不输出任何内容
- 函数的作用域中的
sum
变量保持未初始化状态。
接下来,当您执行该代码时,您定义函数,然后不带参数调用它。你需要最后一行是
some_active_functionm "$@"
此外,如果您想测试 函数 ,您实际上 不需要 到 运行 脚本:
@test "running the file in /src/active_function.sh." {
source ./src/active_function.sh
output=$(some_active_function 9 33)
((output == 42))
}
未经测试。你可能会逃脱
load ./src/active_function.sh
@test "running the file in /src/active_function.sh." {
output=$(some_active_function 9 33)
((output == 42))
}
正如 glenn jackman 的回答中所指出的,我没有在函数的最后一行将传入参数传递给函数。此外,我的求和方法不正确。下面包含一个解决方案(和 non-arithmatic 示例)。
测试和功能:将两个数字相加
一个 shell 脚本,其功能是将两个名为 active_function_addition.sh
的数字相加,内容为:
#!/bin/sh
some_active_function() {
sum=$(expr "" + "")
echo $sum
}
some_active_function "$@"
以及 bats
文件形式的单元测试,名称为 test_active_function_addition.bats
,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function_addition.sh." {
run ./src/active_function_addition.sh 9 33
assert_output 42
}
测试和功能:字符串操作
一个 shell 脚本,具有将名为 active_function_string_manipulation.sh
的大写字符更改为小写字符的功能,内容为:
##################################################################
# Purpose: Converts a string to lower case
# Arguments:
# $@ -> String to convert to lower case
##################################################################
function to_lower()
{
local str="$@"
local output
output=$(tr '[A-Z]' '[a-z]'<<<"${str}")
echo $output
}
to_lower "$@"
以及 bats
文件形式的单元测试,名称为 test_active_function_addition.bats
,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function_string_manipulation.sh." {
input="This Is a TEST"
run ./src/active_function_string_manipulation.sh "This Is a TEST"
assert_output "this is a test"
}
测试结果
两个测试都通过了。
备注
在调试和测试的过程中我确定我漏掉了更多的相关知识。当我 运行 source ./src/active_function.sh; some_active_function 9 33
时,我在某个时间点检索了输出 42
两次。但是,由于我实际上并没有将输入参数传递给函数,因此实际的 return 在干净的设置(例如单元测试)中将无效。当我关闭终端和 re-opened 终端时,我确实在手动测试线上收到了 void return 。我认为在手动尝试不同的求和方法期间,一些变量存储在内存中而我没有意识到这导致 42 在没有传递参数的情况下显示。我没有以受控方式重现此行为。
此解决方案要求整个 shell 脚本为 运行,这可能会花费很多时间。 Glenn jackman 给出了一个更优雅和更有效的解决方案的答案,该解决方案仅 运行 一个特定的功能而无需 运行 一个完整的脚本。
在设置了可以测试某个目录中的 shell 脚本的 bats 测试框架之后,我试图扩展 bats 测试以测试另一个 [=51] 中编写的 shell 函数=] 文件名为 passive_function.sh
.
测试设置
我创建了一个 template repository 来执行 shell 测试。它在文件夹 /test/
中包含一个名为 test_other_shell.bats
的文件,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function.sh." {
run ./src/active_function.sh 9 33
assert_output 42
}
然后我创建了一个名为 main.sh
的文件,内容为:
#!/bin/sh
some_active_function() {
sum=" + " | bc -l
echo "$sum"
}
some_active_function
测试结果
运行 来自终端的蝙蝠测试失败并输出:
✗ running the file in /src/active_function.sh.
(from function `assert_output' in file test/libs/bats-assert/src/assert.bash, line 239,
in test file test/test_active_function.bats, line 8)
`assert_output 42' failed
-- output differs --
expected : 42
actual :
--
功能验证
我通过运行手动验证了这个函数returns 42
:
source ./src/active_function.sh; some_active_function 9 33
来自终端,打印:
42
42
问题
如何编写蝙蝠测试来测试 shell 函数,其中 returns 输入 2 个整数相加?
例如如果我调用 somefunc 3 5
如果函数 returns 8
测试通过,否则失败。
sum=" + " | bc -l
是否不将sum
变量设置为数字的总和:
- 管道意味着 bash 运行 在单独的子 shell 中管道中的每个命令。
- 第一个子 shell
sum
分配了字符串“9 + 33”,并且没有输出 - 第二个子 shell 开始 bc 并向其标准输入发送一个空字符串,因此 bc 不输出任何内容
- 函数的作用域中的
sum
变量保持未初始化状态。
接下来,当您执行该代码时,您定义函数,然后不带参数调用它。你需要最后一行是
some_active_functionm "$@"
此外,如果您想测试 函数 ,您实际上 不需要 到 运行 脚本:
@test "running the file in /src/active_function.sh." {
source ./src/active_function.sh
output=$(some_active_function 9 33)
((output == 42))
}
未经测试。你可能会逃脱
load ./src/active_function.sh
@test "running the file in /src/active_function.sh." {
output=$(some_active_function 9 33)
((output == 42))
}
正如 glenn jackman 的回答中所指出的,我没有在函数的最后一行将传入参数传递给函数。此外,我的求和方法不正确。下面包含一个解决方案(和 non-arithmatic 示例)。
测试和功能:将两个数字相加
一个 shell 脚本,其功能是将两个名为 active_function_addition.sh
的数字相加,内容为:
#!/bin/sh
some_active_function() {
sum=$(expr "" + "")
echo $sum
}
some_active_function "$@"
以及 bats
文件形式的单元测试,名称为 test_active_function_addition.bats
,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function_addition.sh." {
run ./src/active_function_addition.sh 9 33
assert_output 42
}
测试和功能:字符串操作
一个 shell 脚本,具有将名为 active_function_string_manipulation.sh
的大写字符更改为小写字符的功能,内容为:
##################################################################
# Purpose: Converts a string to lower case
# Arguments:
# $@ -> String to convert to lower case
##################################################################
function to_lower()
{
local str="$@"
local output
output=$(tr '[A-Z]' '[a-z]'<<<"${str}")
echo $output
}
to_lower "$@"
以及 bats
文件形式的单元测试,名称为 test_active_function_addition.bats
,内容为:
#!./test/libs/bats/bin/bats
load 'libs/bats-support/load'
load 'libs/bats-assert/load'
@test "running the file in /src/active_function_string_manipulation.sh." {
input="This Is a TEST"
run ./src/active_function_string_manipulation.sh "This Is a TEST"
assert_output "this is a test"
}
测试结果
两个测试都通过了。
备注
在调试和测试的过程中我确定我漏掉了更多的相关知识。当我 运行
source ./src/active_function.sh; some_active_function 9 33
时,我在某个时间点检索了输出42
两次。但是,由于我实际上并没有将输入参数传递给函数,因此实际的 return 在干净的设置(例如单元测试)中将无效。当我关闭终端和 re-opened 终端时,我确实在手动测试线上收到了 void return 。我认为在手动尝试不同的求和方法期间,一些变量存储在内存中而我没有意识到这导致 42 在没有传递参数的情况下显示。我没有以受控方式重现此行为。此解决方案要求整个 shell 脚本为 运行,这可能会花费很多时间。 Glenn jackman 给出了一个更优雅和更有效的解决方案的答案,该解决方案仅 运行 一个特定的功能而无需 运行 一个完整的脚本。