测试用例难写?来试试Sharness

2024-02-14 09:10

本文主要是介绍测试用例难写?来试试Sharness,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

**愿你我相遇,皆有所获! 欢迎关注微信公众号:【伤心的辣条】 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!**

曾经尝试将Git测试用例用作其他项目:《替代git.git测试框架》 [1]。不过从Git项目中替换测试用例框架还是挺费事的。

一次偶然的机会发现已经有人(Christian Couder:Gitlab工程师,Git项目的领导委员会成员之一)已经将Git的测试用例框架替换出来,成为独立的开源项目Sharness。

有了Sharness,写测试用例不再是苦差事。

一Sharness是什么?

  • Sharness是一个用Shell脚本来编写测试用例的测试框架。
  • 可以在Linux,macOS平台上运行测试用例。
  • 测试输出符合TAP(测试任何协议),因此可以使用sharness自身工具或证明等TAP兼容测试夹具(harness)运行。
  • 是由Junio在2005年为Git项目开发的测试框架,由Christian
    Couder(chriscool)从Git中替换为独立测试框架。

地址:https://github.com/chriscool/sharness

二Sharness测试框架的优点

简洁

如果要在测试用例中创建/初始化一个文件(内容为“ Hello,world。”),看看sharness实现起来有多么简单:

cat >expect <<-EOF
Hello, world.
EOF

如果要对某应用(hello-world)的输出和预期的Expect文件进行比较,相同则测试用例通过,不同则展示差异。测试用例编写如下:

test_expect_success “app output test” ‘cat >expect <<-EOF &&Hello, world.EOFhello-world >actual &&test_cmp expect actual
‘

调试方便

每个测试用例脚本可以单独执行。使用-v参数,可以显示详细输出。使用-d参数,运行结束后保留​​用例的临时目录。

可以在要调试的测试案例后面增加test_pause语句,例如:

test_expect_success “name” ‘<Script…>
‘test_pause
test_done

然后使用-v参数运行该脚本,会在test_pause语句处中断,进入一个包含sharness环境变量的子Shell中,目录会切换到测试用例单独的工作区。调试终止退出Shell即返回。

三Git项目的测试框架结构

Sharness源自于Git项目的测试用例框架。我们先来看看Git项目测试框架的结构。

Git项目测试相关文件

  • 待测应用放在项目的根目录。例如Git项目的待测应用:git和git-receive-pack等。
  • 测试框架修改PATH环境变量,进行测试用例在调用待测应用(如git命令)的时候,优先使用项目根目录下的待测应用。
  • 测试脚本命名为tNNNN- .sh ,即以字母t和四位数字开头的脚本文件。
  • 每一个测试用例在执行时会创建一个独立的临时目录,例如垃圾目录。t5323 -pack-redundant。测试用例执行成功,则该目录会被删除。

相关代码参见[2]。

四Git测试脚本的格式

以如下测试脚本为例[3]:

(1)在文件头,定义test_description变量,提供测试用例的简单说明,通常使用一行文本。本测试用例复杂,使用了多行文本进行描述。

 #!/bin/sh## Copyright (c) 2018 Jiang Xin#test_description='Test git pack-redundantIn order to test git-pack-redundant, we will create a number of objects andpacks in the repository `master.git`. The relationship between packs (P1-P8)and objects (T, A-R) is showed in the following chart. Objects of a pack willbe marked with letter x, while objects of redundant packs will be marked withexclamation point, and redundant pack itself will be marked with asterisk.| T A B C D E F G H I J K L M N O P Q R----+--------------------------------------P1  | x x x x x x x                       xP2* |     ! ! ! !   ! ! !P3  |             x     x x x x xP4* |                     ! ! ! !     !P5  |               x x           x xP6* |                             ! !   !P7  |                                 x xP8* |   !----+--------------------------------------ALL | x x x x x x x x x x x x x x x x x x xAnother repository `shared.git` has unique objects (X-Z), while other objects(marked with letter s) are shared through alt-odb (of `master.git`). Therelationship between packs and objects is as follows:| T A B C D E F G H I J K L M N O P Q R   X Y Z----+----------------------------------------------Px1 |   s s s                                 x x xPx2 |         s s s                           x x x'

(2)包含测试框架代码。

 . ./test-lib.sh

(3)定义变量变量,以及定义要在测试用例中用到的函数封装。

 master_repo=master.gitshared_repo=shared.git# Create commits in <repo> and assign each commit's oid to shell variables# given in the arguments (A, B, and C). E.g.:##     create_commits_in <repo> A B C## NOTE: Avoid calling this function from a subshell since variable# assignments will disappear when subshell exits.create_commits_in () {repo="$1" &&if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null)then... ...

(4)用test_expect_success等方法撰写测试用例。

 test_expect_success 'setup master repo' 'git init --bare "$master_repo" &&create_commits_in "$master_repo" A B C D E F G H I J K L M N O P Q R'############################################################################## Chart of packs and objects for this test case##         | T A B C D E F G H I J K L M N O P Q R#     ----+--------------------------------------#     P1  | x x x x x x x                       x#     P2  |     x x x x   x x x#     P3  |             x     x x x x x#     ----+--------------------------------------#     ALL | x x x x x x x x x x x x x x         x##############################################################################test_expect_success 'master: no redundant for pack 1, 2, 3' 'create_pack_in "$master_repo" P1 <<-EOF &&$T$A$B$C$D$E$F$REOFcreate_pack_in "$master_repo" P2 <<-EOF &&$B$C$D$E$G$H$IEOFcreate_pack_in "$master_repo" P3 <<-EOF &&$F$I$J$K$L$MEOF(cd "$master_repo" &&git pack-redundant --all >out &&test_must_be_empty out)'

(5)在脚本的结尾,用test_done方法结束测试用例。

 test_done

五Sharness测试框架结构

Sharness项目由Git项目的测试框架抽象而来,项目地址:https://github.com/chriscool/sharness

  • 待测应用放在项目的根目录。
  • 测试脚本命名为 .t ,即扩展名为.t的脚本文件。
  • 每一个测试用例在执行时会创建一个独立的临时目录,例如垃圾箱directory.simple.t 。测试用例执行成功,则该目录会被删除。
  • 在sharness.d目录下添加自定义脚本,可以扩展Sharness框架。即在框架代码加载时,自动加载该目录下文件。

我们对Sharness测试框架做了一些小植入:

  • 定制版本对测试框架代码进行了进一步封装,框架代码放置了单独的子目录。
  • 测试脚本的名称恢复为和Git项目测试脚本类似的名称(tNNNN- .sh ),即以字母t和四位数字开头的脚本文件。

定制版Sharness测试框架示例

六Sharness测试用例格式

以如下测试脚本为例[4]:

(1)在文件头,定义test_description变量,提供测试用例的简单说明,通常使用一行文本。

 #!/bin/sh     test_description="git-repo init"

(2)包含测试框架代码。

. ./lib/sharness.sh

(3)定义变量变量,以及定义要在测试用例中用到的函数封装。

 # Create manifest repositories manifest_url="file://${REPO_TEST_REPOSITORIES}/hello/manifests"

(4)用test_expect_success等方法撰写测试用例。

 test_expect_success "setup" '# create .repo file as a barrier, not find .repo deepertouch .repo &&mkdir work'test_expect_success "git-repo init -u" '(cd work &&git-repo init -u $manifest_url)'test_expect_success "manifest points to default.xml" '(cd work &&test -f .repo/manifest.xml &&echo manifests/default.xml >expect &&readlink .repo/manifest.xml >actual &&test_cmp expect actual)'

(5)在脚本的结尾,用test_done方法结束测试用例。

 test_done

七关于test_expect_success方法的参数

test_expect_success可以有两个参数或三个参数。

当test_expect_success方法后面是两个参数时,第一个参数用于描述测试用例,第二个参数是测试用例要执行的命令。

test_expect_success 'initial checksum' '(cd bare.git &&git checksum --init &&test -f info/checksum &&test -f info/checksum.log) &&cat >expect <<-EOF &&INFO[<time>]: initialize checksumEOFcat bare.git/info/checksum.log |sed -e "s/\[.*\]/[<time>]/" >actual &&test_cmp expect actual
'

当test_expect_success方法后面是三个参数时,第一个参数是前置条件,第二个参数用于描述测试用例,第三个参数是测试用例要执行的命令。

例如如下有三个参数的测试,第一个参数定义了初步条件,在CYGWIN等环境,不执行测试用例。

test_expect_success !MINGW,!CYGWIN \’correct handling of backslashes' 'rm -rf whitespace &&mkdir whitespace &&>"whitespace/trailing 1  " &&>"whitespace/trailing 2 \\\\" &&>"whitespace/trailing 3 \\\\" &&>"whitespace/trailing 4   \\ " &&>"whitespace/trailing 5 \\ \\ " &&>"whitespace/trailing 6 \\a\\" &&>whitespace/untracked &&sed -e "s/Z$//" >ignore <<-\EOF &&whitespace/trailing 1 \    Zwhitespace/trailing 2 \\\\Zwhitespace/trailing 3 \\\\ Zwhitespace/trailing 4   \\\    Zwhitespace/trailing 5 \\ \\\   Zwhitespace/trailing 6 \\a\\ZEOFecho whitespace/untracked >expect &&git ls-files -o -X ignore whitespace >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 <<-EOF &&$X$Y$Z$A$B$CEOFcreate_pack_in "$shared_repo" Px2 <<-EOF$X$Y$Z$D$E$FEOF
'

自定义方法,也要使用&&级联,确保命令全部执行成功

create_pack_in () {repo="$1" &&name="$2" &&pack=$(git -C "$repo/objects/pack" pack-objects -q pack) &&eval $name=$pack &&eval P$pack=$name:$pack
}

涉及到目录切换,在子Shell中进行,以免影响后续测试用例执行时的工作目录

test_expect_success 'master: one of pack-2/pack-3 is redundant' 'create_pack_in "$master_repo" P4 <<-EOF &&$J$K$L$M$PEOFcreate_pack_in "$master_repo" P5 <<-EOF &&$G$H$N$OEOF(cd "$master_repo" &&cat >expect <<-EOF &&P3:$P3EOFgit pack-redundant --all >out &&format_packfiles <out >actual &&test_cmp expect actual)
'

函数命名要收益

如下内容是Junio在代码评估时,对测试用例中定义的format_git_output方法的评估意见。Junio指出要在给函数命名时,要使用更合理的名称。

> +format_git_output () {Unless this helper is able to take any git output and massage,
please describe what kind of git output it is meant to handle.Also, "format" does not tell anything to the readers why it wants to
transform its input or what its output is supposed to look like.  It
does not help readers and future developers.

Heredoc的小技巧

使用Jundoc创建文本文件,如果其中的脚本要定义和使用变量,要对变量中的 字 符 进 行 转 移 。 J u n i o 称 为 了 一 个 h e r e d o c 语 法 的 小 技 巧 , 可 以 不 必 对 字符进行转移。Junio称为了一个heredoc语法的小技巧,可以不必对 Junioheredoc字符转义。

> +
> +  # setup pre-receive hook
> +  cat >upstream/hooks/pre-receive <<-EOF &&Wouldn't it make it easier to read the resulting text if you quoted
the end-of-here-text marker here, i.e. "<<\-EOF"?  That way, you can
lose backslash before $old, $new and $ref.> +  #!/bin/sh
> +
> +  printf >&2 "# pre-receive hook\n"
> +
> +  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

标记为存在已知问题,执行失败不报错,执行成功则警告该破碎的用例已经固定。

  • t est_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

测试用例结束。

十扩展Sharness

Sharness提供了扩展功能。用户在sharness.d目录中添加以.sh结尾的脚本文件,即可对Sharness进行扩展。例如:

  • 在垃圾箱目录中。*目录下执行git init命令。目的是避免目录逃逸时错误执行git命令影响项目本身代码。

例如:测试脚本在工作区下创建了一个仓库(git init my.repo ),想要在该仓库下执行git clean ,却忘了进入到my.repo子目录再执行,结果导致待测项目中丢失文件。

  • 约会Git项目中的一些有用的测试方法。

如:test_tick方法,可以设置GIT_AUTHOR_DATE ,GIT_COMMITTER_DATE等环境变量,确保测试脚本多次运行时提交时间的一致性,并且产生一致的提交ID。

  • 约会项目需要的其他自定义方法。

例如git-repo项目为了避免工作区逃逸,在垃圾箱目录中。*目录下创建.repo文件。

十一Sharness在项目中的实战

git-repo是一个命令行工具,非常适合使用sharness测试框架编写测试用例。参见[6]。

对于非命令行工具,或者为了测试内置函数,需要先封装一个或多个假应用,再调用封装的命令行工具进行测试。例如在为Git项目开发proc-receive钩子扩展时,先开发一个假应用[7]。

之后再编写测试,调用仿造的app(test-tool proc-receive ),帮助完成测试用例的开发。参见以下提交中的测试用例[8]。

还可以使用一些Shell编程技巧,在多个测试文件中替换测试用例。例如如下测试用例在测试HTTP协议和本地协议时,替换了同一套测试用例(t5411目录下的测试脚本)[9] 。

技术行业,一定要提升技术功底,丰富自动化项目实战经验,这对于你未来几年职业规划,以及测试技术掌握的深度非常有帮助。

金九银十面试季,跳槽季,整理面试题已经成了我多年的习惯!下面有我近几年的收集和整理,整体是围绕着【软件测试】来进行整理的,主体内容包含:python自动化测试专属视频、Python自动化详细资料、全套面试题等知识内容。

对于软件测试的的朋友来说应该是最全面最完整的面试备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer,这个仓库也已经帮助了很多的软件测试的学习者,希望也能帮助到你!

愿你我相遇,皆有所获! 欢迎关注微信公众号:【伤心的辣条】 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!

这篇关于测试用例难写?来试试Sharness的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/708080

相关文章

【Spring boot】编写代码及测试用例入门之 Hello Spring boot _踩坑记

先贴下目录: 这是我从 start.spring.io 里下载的依赖Web的模板 // DemoApplication.javapackage com.abloume.springboot.blog.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autocon

手机扬声器音量总是不够大?试试“扬声器助推器”吧

手机的扬声器音量总是不够大,尤其是在嘈杂的环境中,音乐和视频的声音总是不太清晰。直到我发现了这款“扬声器助推器”,我的手机音质瞬间提升了好几个档次。 软件简介: “扬声器助推器”利用先进的音频处理技术,能够提高手机扬声器的音量,让声音更加清晰响亮。此外,还可以设置最大允许增强量,避免音量过大损坏扬声器。 版本特点: 提升音量效果显著,音质清晰。可以自定义最大增强量,保护扬声器。 使用体

python+selenium2学习笔记unittest-05测试用例实例

看一下非常简单的目录结构 test_baidu from selenium import webdriverimport unittestimport timeclass MyTest(unittest.TestCase):def setUp(self):self.driver = webdriver.Firefox()self.driver.maximize_window()self

【无标题】免费录屏工具推荐,除了OBS还有这几款你也应该试试!

在寻找一款免费且高效的录屏软件时,除了OBS,市场上还有其他多种选择。本文将为您介绍五款易于操作的录屏工具,它们能够满足您在制作教程视频、游戏直播或视频演示时的需求。 首选推荐:嗨格式录屏大师 嗨格式录屏大师以其全面的录制模式(包括全屏、进程、摄像头等七种模式)在视频录制领域占据一席之地。该软件在录制过程中提供工具栏,支持画面标注、聚光灯、高亮等操作,同时具备计划任务录制和自动分段录制

【软件测试】设计测试用例

📕引言 本文章重点目标: 测试用例的概念 设计测试用例的万能思路 设计测试用例的方法 ◦ 基于需求的设计方法◦ 具体的设计方法 ▪ 等价类 ▪ 边界值 ▪ 判定表法 ▪ 正交法 ▪ 场景法 ▪ 错误猜测法 🍀测试用例 🚩概念 什么是测试用例? 测试用例(TestCase)是为了实施测试而向被测试的系统提供的一组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要

redis 实现单位时间内错误记录 时间到key值就被清除------最近脑子不好使觉得还是写个博客试试

直接在客户端操作的, 所以需要redis的简单命令  去对比JAVA客户端jedis的命令就行   添加---set     格式 set  key  value  EX time(秒)   如果这个time不添加的话 ,那默认就是 永久 获取--get    格式 get key  ---查看剩余时间    格式 TTL key ---实现key实现自增: inrc key

还不知道视频合并怎么弄?不妨试试这4个方法

记录生活,就像是在编织一本流动的日记,每一页都充满了色彩和声音。在这个过程中,视频成为了我们记录日常趣事的绝佳方式。 但问题来了,面对手机里零散的视频片段,我们该如何将它们合并,制作成一段流畅的生活Vlog呢? 别急,接下来,本文将为你揭晓“视频合并怎么制作”的秘诀,让你的生活Vlog更加生动有趣! 方法一:使用【剪辑魔法师】进行视频合并 ◆适用人群:适合希望快速拼接视频,又不想花太多

南京大学机试试题合集

🍰🍰🍰hello宝子们,今天我们来练习南京大学的机试题目,这些题目的缺点就是太老了,都是18或19年的题,大家就练练手。加油!fighting!( •̀ ω •́ )✧ 🍩1161 二叉树遍历 #include<bits/stdc++.h>using namespace std;string s;int len;typedef struct node{char dat

谁还只会用OBS?多场景录制试试这四款!

很多人在录屏的时候,尤其是打游戏的朋友,第一时间想到的都是OBS,其实除了这款工具,还有很多好用的第三方录屏工具,一样可以帮助我们录制出不卡顿的高清视频。今天,我们就来对比一下市面上四款热门的录屏软件,看看它们在录制电脑屏幕时的表现如何。 一、福昕录屏大师 网址:https://www.foxitsoftware.cn/REC/ 作为一款第三方工具,我个人还是很喜欢这款的。它支持全屏录制

山东大学机试试题合集

🍰🍰🍰高分篇已经涵盖了绝大多数的机试考点,由于临近预推免,各校的机试蜂拥而至,我们接下来先更一些各高校机试题合集,算是对前边学习成果的深入学习,也是对我们代码能力的锻炼。加油!fighting!( •̀ ω •́ )✧ 我习惯于在注释中解释算法思路,所以可能没有题解,大家可以直接看代码。 🍩1832 字符串的差 #include<bits/stdc++.h>using n