用于重定向shUnit2中文件输出的单元测试bash脚本

问题描述 投票:2回答:1

我正在使用shUnit2在Bash shell脚本中进行单元测试。

我有这样的代码:

cat > /etc/somefile <<EOF
some file content
EOF

我想编写单元测试来测试此代码,但是要做到这一点,我需要避免文件I / O重定向。

我知道我可以重构代码以移动将文件输出重定向到函数内部的位,例如

cat_somefile() {
  cat > /etc/somefile <<EOF
some file content
EOF
}

然后我可以在测试中对这个函数进行打桩。

虽然有什么方法可以测试此代码而不进行重构?

bash unit-testing shunit2
1个回答
1
投票
如@chepner所建议(另请参见ref),chroot可以在这里提供帮助。

全部设置:

1 /授予sudo访问权限以运行chroot命令。

$ sudo visudo ... %admin ALL = (ALL) NOPASSWD: /usr/sbin/chroot

2 /创建一个包含脚本和一个用于设置监狱的功能。

FAKE_ROOT=./fake_root copy_to_jail() { d=$(dirname $1) mkdir -p $FAKE_ROOT/$d cp -p $1 $FAKE_ROOT/$d } jail_files() { # All of these commands are used at least once by one of the # scripts under test. commands=" /bin/cat /bin/chmod /bin/date /bin/mkdir /bin/rm /usr/bin/awk /usr/bin/cut /usr/bin/tee " local OPTIND script wrappers while getopts "s:w:" o do case "${o}" in s) script="${OPTARG}" ;; w) wrappers="${wrappers} ${OPTARG}" ;; esac done shift $((OPTIND-1)) # Without /bin/sh the jail doesn't work. # I didn't spend time to figure out why. for f in /bin/sh $script $wrappers $commands do copy_to_jail $f done # We figure out all the library files we need to build # a working jail just by trying to start it, observing which file # it says is missing, copying the missing file, and repeating # until it starts. case $(uname -s) in Darwin) # Copy Bash 4 and GNU Sed. cp -p /usr/local/bin/bash $FAKE_ROOT/bin cp -p /usr/local/bin/gsed "$FAKE_ROOT/bin/sed" initial_libs=$( for f in /usr/local/bin/bash do otool -L $f | awk 'NR > 1 {print $1}' done | sort -u) initial_libs="/usr/lib/dyld $initial_libs" for f in $initial_libs do copy_to_jail $f done who_i_am=$(whoami) set -o pipefail while true do missing_lib=$(sudo chroot -u $who_i_am $FAKE_ROOT /bin/sh -c echo 2>&1 | \ awk '/dyld: Library not loaded:/ {print $5}') [ "$?" -eq 0 ] && break copy_to_jail $missing_lib done ;; *) echo "Platform $(uname -s) not supported" exit 1 ;; esac } clean_up_jail() { rm -rf $FAKE_ROOT }

3 /在测试文件中:

. shunit2/include.sh script_under_test=path/to/my/script.sh make_jail() { # Copy any binaries that the script depends on # to the jail. jail_files \ -s $script_under_test # Create any directories that are expected to exist. mkdir -p $FAKE_ROOT/etc/apt/preferences.d mkdir -p $FAKE_ROOT/etc/{default,init.d} mkdir -p $FAKE_ROOT/etc/apache2/sites-enabled mkdir -p $FAKE_ROOT/tmp ... # Set up any files with initial content. echo "some initial content" > $FAKE_ROOT/etc/hosts who_i_am=$(whoami) sudo chroot -u $who_i_am $FAKE_ROOT \ /bin/$(basename $script_under_test) > /dev/null } oneTimeSetUp() { make_jail } oneTimeTearDown() { clean_up_jail } # Write actual tests. test_something() { ... } test_something_else() { ... } # Call shUnit2. . shunit2

我将在某个阶段撰写有关此内容的博客文章。
© www.soinside.com 2019 - 2024. All rights reserved.