Last Saturday, I gave a brief presentation on shell scripting and bats, a bash based automated testing system at MashhadBUG. Please Don't forget to check the references at the end of the post.
$ prog > file # direct stdout to file
$ prog >> file # append stdout to file
$ prog < file # take standard input from file
$ < file prog
$ prog1 | prog2 # connect standard output of p1 to standard input of p2
$ prog <<HEREDOC # HereDoc
$ prog1; prog2 # command terminator
$ prog1 & prog2 # like ; but doesn't wait for p1 to finish
$ `prog1` # run command, output replaces
$ (prog1) # run command in sub-shell
$ {prog1} # run command in current-shell
$0...$9 # positional arguments
$# # total number of arguments
$* # all the arguments as a single string (expanded/double-quoted)
$@ # all the arguments as separate strings (expanded/double-quoted)
$$ # pid of current shell process
$! # pid of last background command
$? # exit status of previous command
$var # Value of 'var'
${var} # useful if alphanumerics follows
${var-thing} # 'var' if defined, O.W thing
${var:-word} # 'var' if exists and isn't null, O.W 'word'
${var:=word} # like above but changes var
${var:?message} # abort if var doesn't exist or is null
${var:+word} # returns word if var exists and isn't null
shout() { echo "$0: $*" >&2; }
barf() { shout "$*"; exit 100; }
safe() { "$@" || barf "cannot $*"; }
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
#!/bin/sh
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
# using it
try cd /some/place
tar tar xzvfp /another/place/stuff.tbz
exit 0
Bats is a TAP-compliant testing framework for Bash. It provides a simple way to verify that the UNIX programs you write behave as expected.
TAP, the Test Anything Protocol, is a simple text-based interface between testing modules in a test harness. TAP started life as part of the test harness for Perl but now has implementations in C, C++, Python, PHP, Perl, Java, JavaScript, and others.
1..4
ok 1 - Input file opened
not ok 2 - First line of the input valid
ok 3 - Read the rest of the file
not ok 4 - Summarized correctly # TODO Not written yet
Bats is a TAP-compliant testing framework for Bash. It provides a simple way to verify that the UNIX programs you write behave as expected.
$ git clone https://github.com/sstephenson/bats.git
$ cd bats
$ doas ./install.sh /usr/local
$ cat test.bats
#!/usr/bin/env bats
@test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
@test "addition using dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
$ bats test.bats
✓ addition using bc
✓ addition using dc
WAIT, THAT'S NOT TAP COMPLIANT
$ bats --tap test.bats
1..2
ok 1 addition using bc
ok 2 addition using dc
run
command@test "invoking foo with a nonexistent file prints an error" {
run foo nonexistent_filename
[ "$status" -eq 1 ]
[ "$output" = "foo: no such file 'nonexistent_filename'" ]
}
load
commandload test_helper
skip
command$ cat test.bats
@test "A test I don`t want to execute for now" {
skip "This command will return zero soon, but not now"
run foo
[ "$status" -eq 0 ]
}
Running Skiped Tests
$ bats test.bats
- A test I don`t want to execute for now (skipped: This command will return zero soon, but not now)
1 test, 0 failures, 1 skipped
skip
command (Cont.)@test "A test which should run only when bar is foo" {
[ foo != bar ] && skip "foo isn't bar"
run foo
[ "$status" -eq 0 ]
}
setup
and teardown
functionssetup()
{
/* Initialization call per test calls */
}
teardown()
{
/* Finalization call per test calls */
}
$ cat .travis.yml
before_install:
- sudo add-apt-repository ppa:duggan/bats --yes
- sudo apt-get update -qq
- sudo apt-get install -qq bats
script:
- bats test/bats
config() {
command=""
while read line; do
command+="-c '$line' "
done
bash -c "prog $command"
}
remote() {
host="$1"
command="${@:2}"
ssh $host "$(typeset -f); $command"
}