[英]How to create output in a shell function for unit testing with bats?
After setting up a bats test framework that can test shell scripts in some directory, I am trying to expand the bats tests to test a shell function that is written in another shell file named passive_function.sh
.在设置了可以在某个目录中测试 shell 脚本的 bats 测试框架后,我尝试扩展
passive_function.sh
测试以测试另一个 shell 文件中编写的 shell 函数。
I created a template repository to perform shell testing.我创建了一个模板存储库来执行 shell 测试。 It contains a file called
test_other_shell.bats
in folder /test/
with content:它在文件夹
/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
}
And I created a file called main.sh
with content:我创建了一个名为
main.sh
的文件,内容如下:
#!/bin/sh
some_active_function() {
sum="$1 + $2" | bc -l
echo "$sum"
}
some_active_function
Running the bats test from terminal fails with output:从终端运行 bats 测试失败并输出:
✗ 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 :
--
I manually verified this function returns 42
by running:我通过运行手动验证此函数返回
42
:
source ./src/active_function.sh; some_active_function 9 33
from terminal, which prints:从终端,打印:
42
42
How can I write a bats test that tests a shell function which returns the addition of input 2 integer numbers?如何编写一个 bats 测试来测试一个 shell 函数,该函数返回输入 2 个整数的加法?
Eg if I call somefunc 3 5
the test pass if the function returns 8
, and fail otherwise.例如,如果我调用
somefunc 3 5
测试通过,如果函数返回8
,否则失败。
sum="$1 + $2" | bc -l
does not set the sum
variable to the sum of the numbers:不设置
sum
变量的数字的总和:
sum
assigned the string "9 + 33", and there's no outputsum
分配字符串“9 + 33”,并且没有输出sum
variable in the function's scope remains uninitialized.sum
变量保持未初始化状态。 Next, when you execute that code, you define the function and then invoke it with no parameters.接下来,当您执行该代码时,您定义该函数,然后不带参数调用它。 You need the last line to be
你需要最后一行
some_active_functionm "$@"
Also, if you want to test the function you don't really need to run a script:此外,如果您想测试该功能,您实际上并不需要运行脚本:
@test "running the file in /src/active_function.sh." {
source ./src/active_function.sh
output=$(some_active_function 9 33)
((output == 42))
}
Untested.未经测试。 You could probably get away with
你可能会逃脱
load ./src/active_function.sh
@test "running the file in /src/active_function.sh." {
output=$(some_active_function 9 33)
((output == 42))
}
As indicated in the answer by glenn jackman, I did not pass the incoming arguments to the function in the last line of the function.正如 glenn jackman 的回答所示,我没有在函数的最后一行将传入参数传递给函数。 Furthermore, my summation method was incorrect.
此外,我的求和方法不正确。 A solution (and non-arithmatic example) is included below.
下面包含一个解决方案(和非算术示例)。
A shell script with a function that adds two numbers named active_function_addition.sh
with content:带有一个函数的 shell 脚本,该函数将两个名为
active_function_addition.sh
数字与内容相加:
#!/bin/sh
some_active_function() {
sum=$(expr "$1" + "$2")
echo $sum
}
some_active_function "$@"
And a unit test in the form of a bats
file, with name test_active_function_addition.bats
and content:而在一个形式的单元测试
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
}
A shell script with a function that changes upper case characters to lower case characters named active_function_string_manipulation.sh
with content:带有将大写字符更改为小写字符的函数的 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 "$@"
And a unit test in the form of a bats
file, with name test_active_function_addition.bats
and content:而在一个形式的单元测试
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"
}
Both tests pass.两项测试均通过。
During the debugging and testing I determined I missed more relevant knowledge.在调试和测试期间,我确定我错过了更多相关知识。 When I ran the
source ./src/active_function.sh; some_active_function 9 33
当我运行
source ./src/active_function.sh; some_active_function 9 33
source ./src/active_function.sh; some_active_function 9 33
I retrieved output 42
twice, at some point in time. source ./src/active_function.sh; some_active_function 9 33
我在某个时间点检索了输出42
两次。 However, since I did not actually passed the input arguments to the function, the actual return would be void in a clean setting (eg the unit test).但是,由于我实际上并没有将输入参数传递给函数,因此在干净的设置(例如单元测试)中实际返回将是无效的。 When I closed the terminal and re-opened the terminal I did indeed receive the void return on the manual test line.
当我关闭终端并重新打开终端时,我确实收到了手动测试线上的无效返回。 I think that during the manual tries of different summing methods that some variables were stored in memory without me being aware of that which resulted in the 42 being displayed without the arguments being passed.
我认为在手动尝试不同的求和方法期间,某些变量存储在内存中,而我没有意识到导致 42 显示而没有传递参数的原因。 I did not reproduce this behaviour in a controlled manner.
我没有以受控的方式重现这种行为。
This solution requires the entire shell script to be run, which might take a lot of time.此解决方案需要运行整个 shell 脚本,这可能需要很多时间。 Glenn jackman gave an answer with a more elegant and more efficient solution that only runs a specific function without having to run a complete script.
Glenn jackman 给出了一个更优雅、更高效的解决方案,它只运行特定的功能,而不必运行完整的脚本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.