Skip to content
This repository has been archived by the owner on Apr 29, 2021. It is now read-only.

Manage test dependencies #261

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,75 @@ Or you can skip conditionally:
}
```

### Explicit test names

In most cases, tests don't need to be assigned an explicit name, but some features,
like dependencies described below, reference tests by their names. In such cases,
the test(s) you reference must be assigned an explicit name.

An explicit name is defined using an extension to the base
syntax: replace '@test' by '@test[<explicit_name>]'.

Example:

```bash
@test[mytest1] "Test description..." {
...
```

Notes:

* Every test may define an explicit name, even if it not referenced anywhere,
* In a given test file, each explicit name must be unique. You cannot assign the
same name to different tests,
* Explicit names must be composed from alphanumeric characters + underscore
('_') only.

### Test dependencies

Some tests may have one or more tests as pre-requisites, meaning that tests
are irrelevant if the pre-requisites fail. A common case is test A checking that
service 'foo' is running, while test B and C use this service to retrieve more
information. If service 'foo' is not running, we know for sure that tests B and C will
fail. In such cases, readability is much better if we display test A as failed
and tests B and C as skipped.

In order to implement such a dependency, you will use the 'bats_test_succeeds()'
function. This function returns true (0) if all the test names given as arguments
succeeded, and false if any of them failed.

Example:

```bash
@test[testA] "A pre-requisite check" {
service foo status
}

@test[testAbis] "Oh, I need this too!" {
service bar status
}

# I don't want to run this if pre-requisites are unavailable

@test "Let's check this more in depth..." {
bats_test_succeeds testA testAbis || skip "Pre-requisites are unavailable"
# In-depth check starts here
...
}
```

Notes:

* You cannot define cross-file dependencies. The test(s) you refer to must
be located in the same test file.
* As tests are executed in the order they appear in the file, you can only depend
on tests that appear in the test file BEFORE/ABOVE the current test. If this is
not the case, a warning message is issued on stderr and the parent test is
supposed to be successful (depending test will run).
* Dependencies are transitive/inherited. If a test depends on a test skipped for any reason,
it will be skipped too, along with its descendants.
* You need to set explicit names for the tests you want to create dependencies on.

### `setup` and `teardown`: Pre- and post-test hooks

You can define special `setup` and `teardown` functions, which run
Expand Down Expand Up @@ -199,10 +268,12 @@ test case.
case.
* `$BATS_TEST_NUMBER` is the (1-based) index of the current test case
in the test file.
* `BATS_TEST_RESULTS` is an array of results for tests that ran so far.
Only elements from 1 to $BATS_TEST_NUMBER (excluded) are set. Values are
0 if test succeeded, and different from 0 if test failed.
* `$BATS_TMPDIR` is the location to a directory that may be used to
store temporary files.


## Installing Bats from source

Check out a copy of the Bats repository. Then, either add the Bats
Expand Down
43 changes: 40 additions & 3 deletions libexec/bats-exec-test
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fi

BATS_TEST_DIRNAME="$(dirname "$BATS_TEST_FILENAME")"
BATS_TEST_NAMES=()
BATS_TEST_RESULTS=()

load() {
local name="$1"
Expand Down Expand Up @@ -240,7 +241,7 @@ bats_teardown_trap() {
}

bats_exit_trap() {
local status
local status # Exit code: 0=OK, 1=error, 2=skipped
local skipped
trap - err exit

Expand All @@ -261,21 +262,57 @@ bats_exit_trap() {
else
echo "ok ${BATS_TEST_NUMBER}${skipped} ${BATS_TEST_DESCRIPTION}" >&3
status=0
[ -n "$BATS_TEST_SKIPPED" ] && status=2
fi

rm -f "$BATS_OUT"
exit "$status"
}

bats_test_succeeds() {
local name status index i ret

ret=0

for name in $@
do
index=''
i=0
while [ $i -lt ${#BATS_TEST_NAMES[@]} ; do
if [ "${BATS_TEST_NAMES[$i]}" = "test_$name" ] ; then
index=$i
break
fi
done
if [ -z $index ] ; then
echo "Error: $name: this test name does not exist" >&2
else
status=${BATS_TEST_RESULTS[$index]}
if [ -z $status ] ; then
echo "Warning: $name: Cannot check status as test didn't run yet" >&2
else
[ $status = 0 ] && ret=1
fi
fi
done

return $ret
}

bats_perform_tests() {
local ret status test_number test_name

ret=0
echo "1..$#"
test_number=1
status=0
for test_name in "$@"; do
"$0" $BATS_EXTENDED_SYNTAX "$BATS_TEST_FILENAME" "$test_name" "$test_number" || status=1
"$0" $BATS_EXTENDED_SYNTAX "$BATS_TEST_FILENAME" "$test_name" "$test_number" || status=$?
[ $status = 1 ] && ret=1 # Skip -> OK
BATS_TEST_RESULTS[$test_number]=$status
let test_number+=1
done
exit "$status"
exit "$ret"
}

bats_perform_test() {
Expand Down
14 changes: 9 additions & 5 deletions libexec/bats-preprocess
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,19 @@ encode_name() {

tests=()
index=0
pattern='^ *@test *([^ ].*) *\{ *(.*)$'
pattern='^ *@test(\[([^ ])[^ ]*\])? *([^ ].*) *\{ *(.*)$'

while IFS= read -r line; do
let index+=1
if [[ "$line" =~ $pattern ]]; then
quoted_name="${BASH_REMATCH[1]}"
body="${BASH_REMATCH[2]}"
name="$(eval echo "$quoted_name")"
encoded_name="$(encode_name "$name")"
quoted_name="${BASH_REMATCH[3]}"
if [ -n "${BASH_REMATCH[2]}" ] ; then
encoded_name="test_${BASH_REMATCH[2]}"
else
name="$(eval echo "$quoted_name")"
encoded_name="$(encode_name "$name")"
fi
body="${BASH_REMATCH[4]}"
tests["${#tests[@]}"]="$encoded_name"
echo "${encoded_name}() { bats_test_begin ${quoted_name} ${index}; ${body}"
else
Expand Down