-
Notifications
You must be signed in to change notification settings - Fork 516
Loop around tests? #136
Comments
I'm having this same problem. |
This, as lengthy as it is, is not a definitive guide or a best practice. This is just an in-depth bisection of the problem and my shot at tackling it. Why doesn't it work?To understand why this doesn't work you need to know how Bats executes tests. As you know, a test file is a Bash script with special syntax for defining test cases. Bats is not an interpreter, it doesn't know how to execute a test file. Instead, what it knows is how to translate the special syntax into valid Bash code. This involves replacing Diving deepLet's see an example. #!/usr/bin/env bats
for var in a b c; do
@test "sample test ${var}" {
run echo "${var}"
[ "$output" == "$var" ]
}
done Contrary to what you'd expect, this does not define three different test cases. It defines only one. This becomes apparent when you take a look at the translated, or preprocessed, test file. To copy it before Bats deletes it, add the following snippet to the test file. teardown() {
dbg_save_source './bats-test.src'
}
# Save a copy of the preprocessed test file.
#
# Globals:
# BATS_TEST_SOURCE
# Arguments:
# $1 - [=./bats.$$.src] destination file/directory
# Returns:
# none
dbg_save_source() {
local -r dest="${1:-.}"
cp --reflink=auto "$BATS_TEST_SOURCE" "$dest"
} Now, when you run Bats, the Here it is with the helper functions removed for clarity. #!/usr/bin/env bats
for var in a b c; do
test_sample_test_() { bats_test_begin "sample test ${var}" 10;
run echo "${var}"
[ "$output" == "$var" ]
}
done
# `teardown()' and `dbg_save_source()' were here...
bats_test_function test_sample_test_ The But, as you can see, the loop variable Note: Variables in test descriptsions are expanded because the preprocessor puts it through When the preprocessed script is run, the My solutionTo avoid duplicating code in test cases, extract the common bits into a parametrised helper function and invoke that from each test with the appropriate parameters. #!/usr/bin/env bats
helper() {
local -r var="$1"
run echo "${var}"
[ "$output" == "$var" ]
}
@test "test \`a'" {
helper a
}
@test "test \`b'" {
helper b
}
@test "test \`c'" {
helper c
} Yes, you still need multiple This encourages sharing code and developing reusable helper libraries, that further reduces maintenance. In fact this is how the For a real world example see this test file in Varrick. FAQCan I pass a parameter to No. This is not only not supported by the preprocessor, but also doesn't make sense since you can't call a test case. Even if you could, where would you call the test cases? You would just push the problem one level up. You are on the right track though. Factor out the logic into a test helper and call that with different parameters from the test cases. See Can't I just escape the variable in the description? Nope. The description is encoded to make it suitable for use as a function name, e.g. white-space and other special characters are replaced. The Can I use No. Preprocessing doesn't care about what the code does. It simply manipulates text. Execution comes after this, and then it's already too late. You actually have to have physically separate Can I write a script that generates the test file? Yes, you can. But should you? This adds yet another piece of code that needs maintenance and testing. Your goal is to make your tests easier to read and maintain, not to reduce character count. |
Hi @ztombol, thank you very much for the explanations and also for the links to the other projects. |
This doesn't seem to work
|
nvm, I see my mistake :)
|
I would like to create the following scenario: (Note the
for
loop in the following code)Is there a simple way to achieve this?
The above example runs the tests only for the last variable in the
for
loop (here/var
).Maybe I'm on the wrong track here, but I have may very similar tests, which force me to create copy&paste code - which is something I would like to avoid....
On a side note: Is there a way to pass a parameter to a
@test
? I'm thinking about something like:Thanks in advance!
The text was updated successfully, but these errors were encountered: