shunit_m - posix & portable xunit for shell script
shunit_m [
-hHVvF] [
-A names]
#!/bin/sh
eval "$(shunit_m -v 2 -F)"
_eq 1 1
_neq 1 1 'write anymsg at last arg'
ls
_fail #>> assert $? != 0
_res #>> output result + return rc
--run
~$ sh src.sh #>> ok,NG fail/all=10/20 etc. (bash needs --posix opt)
~$ echo $? #>> output fail num (all suc==0)
- -h, -H, -V
- usage, version
- -v level
- verbose level. 0/1/2 == quite/normal/verbose. output to stderr
- -F
- fallthrough. stops running if detect assert error in default
- -A names
- change assert alias names. set 5 fields
eg) ~$ shunit_m
-A '_eq _neq _suc _fail _res'
#same as default
eg) ~$ shunit_m
-A 'aa bb cc dd zz' #
_eq 1 2 changes to
aa 1 2
shunit_m outputs assert alias, support functions and assert count vars.
core api is alias.
-
_eq
- take 2 args and test [ ag1 = ag2 ]
-
_neq
- take 2 args and test [ ag1 != ag2 ]
-
_suc
- take no arg. same as _eq $? 0
-
_fail
- take no arg. same as _neq $? 0
-
_res
- this isnt assert. output the result and return. if 5 assert failed, $? ==
5.
upper 5 takes additional 1 arg for memo/msg. eg) _suc this_is_f1_test
other functions and vars doesnt use directly. option -v,F,A will edit the output
code and alias. be careful when using it in copy and paste style.
~$ shunit_m #>> shunit_eq(){ abc...}
~$ shunit_m -F #>> shunit_eq(){ xyz...}
*** CAUTION ***
dont eval in compound commands, (), {}, func()(), func(){} etc.
--good | ---NG1 | ---NG2
#!/bin/sh | #!/bin/sh | #!/bin/sh
eval "$(shnit_m)" | ( | testf(){
( | eval "$(shunit_m)" | eval "$(shunit_m)"
_eq 1 1 | _eq 1 1 | _eq 1 1
_res | _res | _res
) | ) | }
| | testf
alias substitution should work as C-lang preprocesser and the scope must be the
same as local vars in posix-shell.
(https://pubs.opengroup.org/onlinepubs/9699919799/utilities/alias.html)
all sample(good, NG1, NG2) should work in posix-shell but any major shells
(posix mode or not) doesnt compliant the standard. only bash is mentioned
about this problem in the alias section of its man.
bash/dash/ksh/busybox raises error to the below code:
sh -c '(alias abc='ls'; alias ; abc)'
# sh == bash --posix / dash / ksh / busybox sh
allmost all shells works fine if eval shunit in `base` process, tread as C-lang
#define delective.
asserts returns 0/!0, _fail 1 2 >> $? == 0.
_res returns
failed assert count.
#!/bin/sh
src_main(){
f1 "$@"
return 0
}
f1(){
[ $# -eq 2 ] || return 1
num=$(($1+$2))
}
### run main or testcode
# src_main "$@"
# exit $?
cmd="$(shunit_m)" #>> output alias, funcs code
eval "$cmd" #>> you can check with 'echo "$cmd"'
# testcode
{
echo "test_start" >&3
f1 ;_fail
f1 1 2 ;_eq 3 $num
} 3>&1 >buf.log 2>&1 ||
(tail buf.log;echo "--test FAILED";exit 1)>/dev/stderr
_res
echo "--test suc"
--test_run
~$ dash src.sh #>> output result
---src.sh
#!/bin/sh
src_main(){
f1 "$@"
return 0
}
f1(){
[ $# -eq 2 ] || return 1
num=$(($1+$2))
}
src_main "$@" # @marker@
--tests.sh
#!/bin/sh
eval "$(shunit_m -F)"
test_1(){ f1 10 20; _fail ;}
test_2(){ _eq 1 1 ;}
eval "$(cat src.sh|grep -v '@marker@')"
suite=$(sed -ne '/^test_[0-9]*[(]/{s/[(].*//p}'<$0) #grep test_**
for fc in $suite;do $fc ;done
_res
--test_run
~$ bash --posix tests.sh
~$ shunit_m -F #>> output code
--tests.sh
#!/bin/sh
#---
# copy&paste code
#---
test_1(){ _eq 1 1 ;}
eval "$(cat src.sh|grep -v '@marker@')"
suite=$(sed -ne '/^test_[0-9]*[(]/{s/[(].*//p}'<$0)
for fc in $suite;do $fc ;done
_res
--test_run--
~$ sh tests.sh
--concept
- respect posix
- small is beautiful
- avoid original syntax
posix-shell
Copyright (C) 2021 Momi-g
License GPLv3+ <https://gnu.org/licenses/gpl.html>
2021-09-12 v1.0.2
shunit2(1), shellspec