Tree @v1.5.0 (Download .tar.gz)
Code coverage for Bash
- Source Code
- Bug Tracker
- API Documentation
- Continuous Integration
You should check out these coverage examples - it's worth a thousand words:
$ gem install bashcov
$ bashcov --help prints all available options.
Here are some examples:
$ bashcov ./script.sh $ bashcov --skip-uncovered ./script.sh $ bashcov -- ./script.sh --some --flags $ bashcov --skip-uncovered -- ./script.sh --some --flags
script.sh can be a mere Bash script or typically your CI script.
Bashcov will keep track of all executed scripts.
Then it will create a directory named
./coverage/ containing nice HTML files.
./coverage/index.html to browse the coverage report.
Some gory details
Figuring out where an executing Bash script lives in the file system can be
surprisingly difficult. Bash offers a fair amount of introspection into its
but the location of the current script has to be inferred from the limited
information available through
DIRSTACK if you are using
popd). For this purpose,
Bashcov puts Bash in debug mode and sets up a
PS4 that expands the values of
these variables, reading them on each command that Bash executes. But, given
BASH_SOURCEis only an absolute path if the script was invoked using an absolute path,
- the builtins
- none of these variables are read-only and can therefore be
unsetor otherwise altered,
it can be easy to lose track of where we are.
"Wait a minute, what about
readlink, and so on?" That would be great,
except that subshells executed as part of expanding the
PS4 can cause Bash to
report extra executions
for certain lines. Also,
subshells are slow as the
PS4 is expanded on each and every command when Bash
is in debug mode.
To deal with these limitations, Bashcov uses the expedient of maintaining two
stacks that track changes to
OLDPWD. To determine the full path to
the executing script, Bashcov iterates in reverse over the
PWD stack, testing
for the first
$PWD/$BASH_SOURCE combination that refers to an existing file.
This heuristic is susceptible to false positives -- under certain combinations
of directory structure, script invocation paths, and working directory changes,
it may yield a path that doesn't refer to the currently-running script.
However, it performs well under the various working directory changes performed
in the test app demo and avoids the spurious extra hits caused by using
subshells in the
One final note on innards: Bash 4.3 fixed a bug in which
PS4 expansion is
truncated to a maximum of 128 characters. On platforms whose Bash version
suffers from this bug, Bashcov uses the ASCII record separator character to
PS4 fields, whereas it uses a long random string on Bash 4.3 and
above. When the field delimiter appears in the path of a script under test or
in a command the script executes, Bashcov won't correctly parse the
will abort early with incomplete coverage results.
Bug reports and patches are most welcome. See the contribution guidelines.
git clone https://git.infertux.com/bashcov/
- Bump version to 1.5.0 Cédric Félizard 2 years ago
- Update CHANGELOG Cédric Félizard 2 years ago
- Bump LICENSE year Cédric Félizard 2 years ago
- Fix incorrect coverage for some multiline strings Cédric Félizard 2 years ago
- Don't run slow test by default Cédric Félizard 2 years ago
- Improve mutation coverage Cédric Félizard 2 years ago
- Run newest versions first Cédric Félizard 2 years ago
- Update RubyGems to fix build Cédric Félizard 2 years ago
- Check code metrics with Rubocop Cédric Félizard 2 years ago
- Set up Mutant Gem Cédric Félizard 2 years ago