Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
35 changes: 33 additions & 2 deletions docs/source/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ can view the available command line options that Bats supports by calling Bats
with the `-h` or `--help` options. These are the options that Bats currently
supports:

``` eval_rst
```eval_rst
.. program-output:: ../../bin/bats --help
```

Expand Down Expand Up @@ -85,7 +85,7 @@ $ cat /tmp/report.xml

## Parallel Execution

``` eval_rst
```eval_rst
.. versionadded:: 1.0.0
```

Expand All @@ -110,5 +110,36 @@ If you have files where tests within the file would interfere with each other, y
If you want more fine-grained control, you can `export BATS_NO_PARALLELIZE_WITHIN_FILE=true` in `setup_file()`
or outside any function to disable parallelization only within the containing file.

## Test Coverage

Test coverage can be gathered when using [run][run-test-other-commands] to run
the code being tested as an external binary; it is not possible to gather test
coverage for shell functions because shell functions cannot be run by an
external program, and attempting to do so will likely cause the tests to fail.

Bats does not create or cleanup the test coverage directory, allowing
accumulation of coverage data over multiple runs.

Only [kcov][kcov] is currently supported:

- To enable test coverage globally use `--kcoverage_dir <directory>`.
Copy link
Contributor

@AlexSkrypnyk AlexSkrypnyk Sep 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if kcov is potentially replaceable with another coverage tool, should the API defined in a more generic way?
--coverage-dir option and BATS_COVERAGE_DIR env var

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'm happy to change the API - maybe something like this would be better?

  • --coverage_dir and $BATS_COVERAGE_DIR
  • --coverage_tool and $BATS_COVERAGE_TOOL

Then only gather_coverage would need changes to support a new coverage tool.

- Test coverage can be selectively enabled by setting or clearing the
environment variable `KCOVERAGE_DIR` before calling `run`.

Other programs for gathering test coverage can be supported by redefining the
`gather_coverage` function, e.g.:

```shell
gather_coverage() {
my-coverage-program --flag1 --flag2 "$@"
}
```

If you would like to contribute support for other test coverage systems please
search for `gather_coverage`, `kcoverage_dir`, and `KCOVERAGE_DIR` to find the
code that will need to be extended.

[tap-format]: https://testanything.org
[gnu-parallel]: https://www.gnu.org/software/parallel/
[run-test-other-commands]: writing-tests.html#run-test-other-commands
[kcov]: https://github.com/SimonKagstrom/kcov
24 changes: 20 additions & 4 deletions lib/bats-core/test_functions.bash
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,28 @@ load() {
fi
}

# This is a hook enabling users to gather coverage when using `run()`.
#
# You can run anything in this function so it should be possible to support most
# (all?) coverage systems.
#
# Limitations: only works for external binaries, shell functions are not
# supported.
gather_coverage() {
if [[ -n "${KCOVERAGE_DIR:-}" ]]; then
kcov --bash-dont-parse-binary-dir \
"${KCOVERAGE_DIR}" "$@"
else
"$@"
fi
}

bats_redirect_stderr_into_file() {
"$@" 2>>"$bats_run_separate_stderr_file" # use >> to see collisions' content
gather_coverage "$@" 2>>"$bats_run_separate_stderr_file" # use >> to see collisions' content
}

bats_merge_stdout_and_stderr() {
"$@" 2>&1
gather_coverage "$@" 2>&1
}

# write separate lines from <input-var> into <output-array>
Expand Down Expand Up @@ -421,7 +437,7 @@ run() { # [!|-N] [--keep-empty-lines] [--separate-stderr] [--] <command to run..
if [[ ${BATS_VERBOSE_RUN:-} ]]; then
bats_run_print_output
fi

# don't leak our trap into surrounding code
trap bats_interrupt_trap INT
}
Expand Down Expand Up @@ -495,7 +511,7 @@ bats_test_function() {
BATS_TEST_TAGS=("${tags[@]+${tags[@]}}")
export BATS_TEST_DESCRIPTION="${test_description-$*}"
# shellcheck disable=SC2034
BATS_TEST_COMMAND=("$@")
BATS_TEST_COMMAND=("$@")
fi
}

Expand Down
11 changes: 10 additions & 1 deletion libexec/bats-core/bats
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ abort() {

usage() {
local cmd="${0##*/}"
local line

cat <<HELP_TEXT_HEADER
Usage: ${cmd} [OPTIONS] <tests>
Expand Down Expand Up @@ -63,6 +62,10 @@ HELP_TEXT_HEADER
as files in directory (if existing, must be empty)
-h, --help Display this help message
-j, --jobs <jobs> Number of parallel jobs (requires GNU parallel or shenwei356/rush)
--kcoverage_dir <directory>
Gather test coverage with kcov(1). See
https://bats-core.readthedocs.io/en/stable/usage.html#test-coverage
for details and limitations.
--parallel-binary-name Name of parallel binary
--no-tempdir-cleanup Preserve test output temporary directory
--no-parallelize-across-files
Expand Down Expand Up @@ -294,6 +297,12 @@ while [[ "$#" -ne 0 ]]; do
shift
BATS_LINE_REFERENCE_FORMAT=$1
;;
--kcoverage_dir)
shift
# shellcheck disable=SC2034
KCOVERAGE_DIR=$1
export KCOVERAGE_DIR
;;
-*)
abort "Bad command line option '$1'"
;;
Expand Down
12 changes: 6 additions & 6 deletions man/bats.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ OPTIONS
Count the number of test cases without running any tests
* `--code-quote-style <style>`:
A two character string of code quote delimiters or `custom`
which requires setting `$BATS_BEGIN_CODE_QUOTE` and
`$BATS_END_CODE_QUOTE`.
which requires setting `$BATS_BEGIN_CODE_QUOTE` and
`$BATS_END_CODE_QUOTE`.
Can also be set via `$BATS_CODE_QUOTE_STYLE`.
* `--line-reference-format`
Controls how file/line references e.g. in stack traces are printed:
Expand All @@ -101,7 +101,7 @@ OPTIONS
failed - runs tests that failed or were not present in the last run
missed - runs tests that were not present in the last run
* `--filter-tags <comma-separated-tag-list>`:
Only run tests that match all the tags in the list (`&&`). You can negate a
Only run tests that match all the tags in the list (`&&`). You can negate a
tag via prepending `!`.
Specifying this flag multiple times allows for logical or (`||`):
`--filter-tags A,B --filter-tags A,!C` matches tags `(A && B) || (A && !C)`
Expand All @@ -111,6 +111,9 @@ OPTIONS
Display this help message
* `-j`, `--jobs <jobs>`:
Number of parallel jobs (requires GNU parallel)
* `--kcoverage_dir <directory>`:
Gather test coverage with kcov(1). See https://bats-core.readthedocs.io/en/stable/usage.html#test-coverage
for details and limitations.
* `--no-tempdir-cleanup`:
Preserve test output temporary directory
* `--no-parallelize-across-files`:
Expand Down Expand Up @@ -187,6 +190,3 @@ COPYRIGHT
(c) 2011-2016 Sam Stephenson

Bats is released under the terms of an MIT-style license.



48 changes: 46 additions & 2 deletions test/bats.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ END_OF_ERR_MSG
[ "${lines[0]}" = 1..1 ]
[ "${lines[1]}" = 'not ok 1 setup_file failed' ]
[ "${lines[2]}" = "# (from function \`setup_file' in test file $RELATIVE_FIXTURE_ROOT/failure_callback_setup_file.bats, line 6)" ]
[ "${lines[3]}" = "# \`false' failed" ]
[ "${lines[3]}" = "# \`false' failed" ]
[ "${lines[4]}" = '# failure callback' ]
[ ${#lines[@]} -eq 5 ]
}
Expand All @@ -1551,4 +1551,48 @@ END_OF_ERR_MSG
[ "${lines[3]}" = "# \`false' failed" ]
[ "${lines[4]}" = '# failure callback' ]
[ ${#lines[@]} -eq 5 ]
}
}

@test "Coverage is enabled with --kcoverage_dir" {
bats_require_minimum_version 1.5.0
# Deliberately using a directory I can't write to.
reentrant_run -0 bats --kcoverage_dir "/TMPDIR/FOO" \
"$FIXTURE_ROOT/kcoverage.bats"
}

@test "Coverage is controlled by KCOVERAGE_DIR" {
bats_require_minimum_version 1.5.0
# Set up a fake kcov.
local output_file="${BATS_TEST_TMPDIR}/kcov-was-run"
cat > "${BATS_TEST_TMPDIR}/kcov" <<FAKE_KCOV
!#/bin/bash

echo "\$@" > "${output_file}"
FAKE_KCOV
chmod 755 "${BATS_TEST_TMPDIR}/kcov"
PATH="${BATS_TEST_TMPDIR}:${PATH}"

# First run: coverage is disabled.
reentrant_run -0 true
[[ ! -e "${output_file}" ]]

# Second run: coverage is enabled.
KCOVERAGE_DIR="/TMPDIR/FOO"
export KCOVERAGE_DIR
reentrant_run -0 true
[[ -e "${output_file}" ]]
local output_contents
output_contents="$(< "${output_file}")"
local expected="--bash-dont-parse-binary-dir /TMPDIR/FOO"
expected+=" execute_with_unset_bats_vars true"
if [[ "${output_contents}" != "${expected}" ]]; then
echo "Bad output: expecting \"${expected}\", got \"${output_contents}\"" >&2
false
fi
unset KCOVERAGE_DIR
rm "${output_file}"

# Third run: coverage is disabled.
reentrant_run -0 true
[[ ! -e "${output_file}" ]]
}
23 changes: 23 additions & 0 deletions test/fixtures/bats/kcoverage.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@test "kcov is invoked correctly" {
bats_require_minimum_version 1.5.0
local output_file="${BATS_TEST_TMPDIR}/kcov-was-run"
cat > "${BATS_TEST_TMPDIR}/kcov" <<FAKE_KCOV
!#/bin/bash

echo "\$@" > "${BATS_TEST_TMPDIR}/kcov-was-run"
FAKE_KCOV
chmod 755 "${BATS_TEST_TMPDIR}/kcov"

# Use our fake kcov.
PATH="${BATS_TEST_TMPDIR}:${PATH}"
run -0 true

[[ -e "${output_file}" ]]
local output_contents
output_contents="$(< "${output_file}")"
local expected="--bash-dont-parse-binary-dir /TMPDIR/FOO true"
if [[ "${output_contents}" != "${expected}" ]]; then
echo "Bad output: expecting \"${expected}\", got \"${output_contents}\"" >&2
false
fi
}