shunit_m - posix & portable xunit for shell script
shunit_m [
-hHVvF] [
-A names]
~$ shunit_m > funcs.sh
--src.sh
#!/bin/sh
. ./funcs.sh
_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
- takes 2 args and test [ ag1 = ag2 ]
-
_neq
- takes 2 args and test [ ag1 != ag2 ]
-
_suc
- takes no arg. same as _eq $? 0
-
_fail
- takes 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...}
---
dont eval in compound commands, (), {}, func()(), func(){} etc.
--good | ---NG1 | ---NG2
#!/bin/sh | #!/bin/sh | #!/bin/sh
eval "$(shunit_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 macros 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_m 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
# src_main "$@"
# exit $?
## run testcode
cmd="$(shunit_m)"
eval "$cmd" #>> you can check with 'echo "$cmd"'
f1 ;_fail
f1 1 2 ;_eq 3 $num
_res
echo "--test suc"
--test_run
~$ dash src.sh
---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-10-12 v1.0.3
shunit2(1), shellspec