参与过 Git 项目的测试用例开发,为其测试框架的简洁、高效而折服。曾经尝试将 Git 测试用例用于其他项目:《复用 git.git 测试框架》[1]。不过从 Git 项目中剥离测试用例框架还是挺费事的。
一次偶然的机会发现已经有人(Christian Couder:Gitlab 工程师,Git项目的领导委员会成员之一)已经将 Git 的测试用例框架剥离出来, 成为独立的开源项目 Sharness。
有了 Sharness,写测试用例不再是苦差事。
一 Sharness 是什么?- Sharness 是一个用 Shell 脚本来编写测试用例的测试框架。
- 可以在 Linux、macOS 平台运行测试用例。
- 测试输出符合 TAP(test anything protocol),因此可以用 sharness 自身工具或 prove 等 TAP 兼容测试夹具(harness)运行。
- 是由Junio在2005年为Git项目开发的测试框架,由 Christian Couder (chriscool) 从 Git 中剥离为独立测试框架。
- 地址:https://github.com/chriscool/sharness
如果要在测试用例中创建/初始化一个文件(内容为 “Hello, world.”), 看看 sharness 实现起来有多么简单:
cat >expect "whitespace/trailing 3 \\\\" &&
>"whitespace/trailing 4 \\ " &&
>"whitespace/trailing 5 \\ \\ " &&
>"whitespace/trailing 6 \\a\\" &&
>whitespace/untracked &&
sed -e "s/Z$//" >ignore actual 2>err &&
test_cmp expect actual &&
test_must_be_empty err
'
八 Sharness 语法规范和技巧
使用 && 级联各个命令,确保所有命令都全部执行成功
test_expect_success 'shared: create new objects and packs' '
create_commits_in "$shared_repo" X Y Z &&
create_pack_in "$shared_repo" Px1 +
> + while read old new ref
> + do
> + printf >&2 "pre-receive< \$old \$new \$ref\n"
> + done
> + EOF
Shell 编程语法规范
Git 项目对于 Shell 编写的测试用例制定了语法规范,例如:
- 使用 tab 缩进。
- 规定 case 语句、if 语句的缩进格式。
- 输入输出重定向字符后面不要有空格。
- 使用 $(command) 而不是
command
。 - 使用 test 方法,不要使用 [ ... ] 。
完整语法规范参考[5]。
九 sharness 常见的内置函数- test_expect_success
开始一个测试用例。
- test_expect_failure
标记为存在已知问题,执行失败不报错,执行成功则警告该 broken 的用例已经 fixed。
- test_must_fail
后面的一条命令必须失败。如果后面命令成功,测试失败。
- test_expect_code
命令以给定返回值结束。
- test_cmp
比较两个文件内容,相同成功,不同失败并显示差异。
- test_path_is_file
参数必须是一个文件,且存在。
- test_path_is_dir
参数必须是一个目录,且存在。
- test_must_be_empty
参数指向的文件内容必须为空。
- test_seq
跨平台的 seq,用户生成数字序列。
- test_pause
测试暂停,进入子 Shell。
- test_done
测试用例结束。
十 扩展 SharnessSharness 提供了扩展功能。用户在 sharness.d 目录中添加以 .sh 结尾的脚本文件,即可对 Sharness 进行扩展。例如:
- 在 trash directory.* 目录下执行 git init 命令。目的是避免目录逃逸时误执行 git 命令影响项目本身代码。
例如:测试脚本在工作区下创建了一个仓库(git init my.repo),想要在该仓库下执行 git clean,却忘了进入到 my.repo 子目录再执行,结果导致待测试项目中丢失文件。
- 引入 Git 项目中的一些有用的测试方法。
如:test_tick 方法,可以设置 GIT_AUTHOR_DATE、GIT_COMMITTER_DATE 等环境变量,确保测试脚本多次运行时提交时间的一致性,进而产生一致的提交ID。
- 引入项目需要的其他自定义方法。
例如 git-repo 项目为了避免工作区逃逸,在 trash directory.* 目录下创建 .repo 文件。
十一 Sharness 在项目中的实战git-repo 是一个命令行工具,非常适合使用 sharness 测试框架编写测试用例。参见[6]。
对于非命令行工具,或者为了测试内置函数,需要先封装一个或多个 fake app,再调用封装的命令行工具进行测试。例如在为 Git 项目开发 proc-receive 钩子扩展时,先开发一个 fake app[7]。
之后再编写测试,调用 fake app(test-tool proc-receive),帮助完成测试用例的开发。参见下列提交中的测试用例[8]。
还可以使用一些 Shell 编程技巧,在多个测试文件中复用测试用例。例如如下测试用例在测试 HTTP 协议和本地协议时,复用了同一套测试用例(t5411目录下的测试脚本)[9]。
相关链接
[1]https://www.worldhello.net/2013/10/26/test-gistore-using-git-test-framework.html[2]https://sourcegraph.com/github.com/git/git@master/-/tree/t[3]https://github.com/git/git/blob/master/t/t5323-pack-redundant.sh[4]https://github.com/alibaba/git-repo-go/blob/master/test/t0100-init.sh[5]https://github.com/git/git/blob/master/Documentation/CodingGuidelines[6]https://github.com/alibaba/git-repo-go[7]https://github.com/jiangxin/git/blob/jx/proc-receive-hook/t/helper/test-proc-receive.c[8]https://github.com/jiangxin/git/commit/9654f5eda1153634ab09ca5c6e490bcabdd57e61[9]https://github.com/jiangxin/git/blob/jx/proc-receive-hook/t/t5411-proc-receive-hook.sh
原文链接:https://developer.aliyun.com/article/770948?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。