当前位置: 首页 > 编程日记 > 正文

bats-Bash自动化测试工具

本文分析了bats--Bash自动化测试工具的安装、语法、常用指令及常用函数等内容。
上篇文章回顾:学习RAID 01/10/10E的区别

bats 是一个符合 TAP 标准 的 Bash 版测试框架,它使用了一种极为简便的方法来验证命令行程序是否正常运行。

bats 要求 Bash 的最低版本是 3.2.57 ,bats 测试文件实际上一个 bash 的脚本文件,完全可以使用 shell 的语法书写。

一、安装

强烈建议使用源码或者npm安装最新版本, bats 经过多人接手,代码存放比较混乱,某些系统下安装的是旧版本的,目前社区在维护的版本地址为:

https://github.com/bats-core/bats-core.git

01macOS下安装

brew install bats-core复制代码

02CentOS下安装

yum install bats复制代码

03UBuntu下安装

apt-get install bats复制代码

04Windows安装

Windows 平台需要 bash 环境可以使用以下任意一个
  1. Git for Windows Bash (MSYS2 based)

  2. Windows Subsystem for Linux

  3. MSYS2

  4. Cygwin

Windows下推荐使用源码安装或者 npm 的方式进行安装

05使用源码安装

git clone https://github.com/bats-core/bats-core.gitcd bats-core
./install.sh /usr/local
复制代码

06使用Docker安装

docker pull bats/bats
docker run -it --rm bats/bats --version
docker run -it --rm -v "$(pwd):/code" bats/bats /code/test复制代码

07使用npm安装

npm install -g bats复制代码

经过测试 CentOS 下的版本为 2014 年的版本,ubuntu下也不是最新版本,建议使用源码或者npm安装最新版本。

二、语法

测试用例的语法格式为:

#!/usr/bin/env bats@test "grep --version check" {         # 测试用例名称run grep --version                   # 运行的外部命令[ $status -eq 0 ]                    # 断言[ "${lines[0]%% *}" == 'grep' ]      # 断言
}复制代码

每个 Bats 测试文件的评估次数为 n + 1 次,其中 n 是文件中的测试用例数。运行测试脚本时首先计算测试用例的数量,然后遍历测试用例并在独立进程中执行每个测试用例。

在运行测试用例时,Bats使用Bash的 errexit(set -e)选项,这样写在@test 里面的语句都是真理断言。一旦测试用例中的某一个断言失败(某条语句的状态码不是 0)则这个测试用例视为失败。

三、常用指令

01run:运行外部命令

用于测试外部命令然后对它的退出状态和输出状态进行断言。Bats 包含一个 run 的指令,它可以将传入的参数当成命令调用,并且将退出状态和输出状态保存到特殊的全局变量中,以便可以继续在测试用例中增加断言。

比如说我们正在测试 cat:

#!/usr/bin/env bats@test "cat nonexistent_filename check" {                                    # 测试用例名称run cat nonexistent_filename                                              # 运行的外部命令[ $status -eq 1 ]                                                         # 断言[ "$output" == 'cat: nonexistent_filename: No such file or directory' ]   # 断言[ "${lines[0]}" == 'cat: nonexistent_filename: No such file or directory' ] # 断言
}复制代码

这里有三个 Bats 的特殊变量

$status 是命令退出状态码

$output 是命令的标准输出和标准错误的内容

$lines是命令输出内容的数组包含各行内容 cat nonexistent_filename 只有一行内容

02load:使用共享文件

如果想用跨越多个测试文件共享环境变量或者自定义的函数,可以使用 load 指令。共享文件的扩展文件名必须是.bash。load可以使用相对路径或者绝对路径。

使用相对路径的写法是(可以省略扩展文件名):

load test_helper复制代码

使用绝对路径的写法时(必须带上扩展文件名):

load /test_helpers/test_helper.bash复制代码

03skip:跳过测试

在测试过程中如果失败时如果想继续可以 skip 指令来跳过测试:

@test "A test I don't want to execute for now" {skiprun foo[ "$status" -eq 0 ]
}复制代码

也可以加入跳过原因:

@test "A test I don't want to execute for now" {skip "This command will return zero soon, but not now"run foo[ "$status" -eq 0 ]
}复制代码

或者也可以根据条件判断是否跳过:

@test "A test which should run" {  if [ foo != bar ]; thenskip "foo isn't bar"firun foo[ "$status" -eq 0 ]
}复制代码

四、常用函数

01@test

这是 Bats 主要的函数所有的测试用例都要按照这个函数的格式书写:

@test "grep --version check" {         # 测试用例名称run grep --version                   # 运行的外部命令[ $status -eq 0 ]                    # 断言[ "${lines[0]%% *}" == 'grep' ]      # 断言
}复制代码

02setup/teardown初始化和善后函数

setup / teardown 是两个特殊的函数,用于在测试用例开始之前和结束之后进行初始化和善后工作。比如开始之前设置环境变量创建测试目录。以 soar 为测试用例为例:

setup() {export SOAR_DEV_DIRNAME="${BATS_TEST_DIRNAME}/../"export SOAR_BIN="${SOAR_DEV_DIRNAME}/bin/soar" export SOAR_BIN_ENV="${SOAR_DEV_DIRNAME}/bin/soar -config ${SOAR_DEV_DIRNAME}/etc/soar.yaml" export BATS_TMP_DIRNAME="${BATS_TEST_DIRNAME}/tmp"export BATS_FIXTURE_DIRNAME="${BATS_TEST_DIRNAME}/fixture"mkdir -p "${BATS_TMP_DIRNAME}"}teardown(){  //TODO......
}复制代码

五、特殊变量

Bats 中包含几个全局变量 :

  1. $BATS_TEST_FILENAME Bats测试文件的绝对路径。

  2. $BATS_TEST_DIRNAME Bats测试文件所在的目录。

  3. $BATS_TEST_NAMES 每个测试用例的函数名称数组。

  4. $BATS_TEST_NAME 包含当前测试用例的函数的名称。

  5. $BATS_TEST_DESCRIPTION 当前测试用例的描述。

  6. $BATS_TEST_NUMBER 测试文件中当前测试用例的(从1开始)索引。

  7. $BATS_TMPDIR 用于存储临时文件的目录的位置。

六、注意事项

01写在@test之外的代码

写在 @test 函数之外代码一旦失败 Bats 会立刻中断执行,某些情况下这样做会很有用比如检查依赖项,但是如果在@test、setup、teardown之外打印的任何输出必须重定向到stderr(>&2),否则这些输出内容可能会污染TAP流导致Bats 测试失败。

经过测试 @test 之外的代码会优先执行

02文件描述符3(FD3)

如果Bats卡死可以读这一块内容。

Bats 将测试代码的输出流和 TAP 输出流分开,这样做的目的是为了确保 TAP 的输出不被污染。在输出至终端的部分详细介绍了如何使用 FD3 正确打印自定义文本。

但是使用 FD3 的一个已知的问题是:在某些情况下(如程序的子进程在后台运行的时候),它会导致 Bats 卡死。在这种情况下在生成子进程的时候,子进程会从父进程继承 FD3 ,导致Bats 会等待子进程执行完成之后关闭 FD3 。如果子进程需要花费大量时间完成,例如,如果子进程是 sleep 100 命令或是后台服务,那么 Bats 也会阻塞同样的时间。

为了避免这种情况,启动可能长时间运行的子进程之前显式关闭 FD3 command_name 3>&-

举例说明:

1.会卡死的情况:

@test "cat nonexistent_filename check" {            # 测试用例名称run cat nonexistent_filenamesleep 100  &                                      # 后台执行[ $status -eq 1 ]       [ "$TTTT" -eq 1 ]                                 # 断言[ "$output" == 'cat: nonexistent_filename: No such file or directory' ]   # 断言
}复制代码

2. 不会卡死的情况:

@test "cat nonexistent_filename check" {                # 测试用例名称run cat nonexistent_filenamesleep 100 3>&- &                                      # 后台执行并且关闭文件描述符3[ $status -eq 1 ]       [ "$TTTT" -eq 1 ]                                     # 断言[ "$output" == 'cat: nonexistent_filename: No such file or directory' ]   # 断言
}复制代码

03命令输出到终端

  1. 在 @test 函数内部输出

(1)如果从@test 内部输出字符你需要将输出重定向到 FD3 例如 echo 'test'>&3。这时输出将变成 TAP 流的一部分。为了生成100%符合 TAP 流格式的输出,我们推荐的写法是 echo '# text' >&3 。否则,在使用分析 TAP 流的第三方工具时可能会遇到意外错误。

(2)Bats 默认使用友好的输出格式(-p, --pretty)。 TAP 流默认不会从 FD3 中输出任何字符

(3)无论指定何种输出格式,直接输出到 stdout、stderr 的文本(例如 echo "aaaa")会被@test 视为测试的一部分,仅仅在测试失败的时候显示。

在 setup/teardown 函数内部输出

这一部分内容输出行为和@test 中一样。

在 @test 或者setup/teardown 外部输出

(1)无论输出的字符被重定向到何处(FD1、FD2、FD3)字符都会立刻显示到终端

(2)按照这种方式打印的文本将会禁用友好的输出格式(-p, --pretty)。此外他也会使得输出不符合 TAP 流规范。

(3)由内部管道或者重定向输出到标准错误的字符总会第一时间显示出来。

七、Bats命令行用法

bats 命令行用法:

Bats 1.1.0  Usage: bats [-cr] [-f <regex>] [-p | -t] <test>...bats [-h | -v]<test>  为一个 bats 测试用例的文件,或者是一个包含后缀名为 .bats 文件的目录-c, --count      计算没有运行的测试用例的个数-f, --filter     通过正则表达式指定运行某些测试用例-h, --help       显示帮助信息-p, --pretty     以比较友好的方式展现测试用例的输出结果(默认是使用这种方式)-r, --recursive  在子目录中包含测试-t, --tap        以 TAP 格式显示输出结果-v, --version    显示版本号信息复制代码

更多信息见:

https://github.com/bats-core/bats-core复制代码

八、开发工具推荐

在常用的开发工具中安装 Bats 插件,增加代码高亮显示和代码完成提示,提高开发效率。

01VS Code

02Sublime Text

03Vim

九、其他开发工具

更多开发工具和插件参考:

github.com/bats-core/b…

十、参考文献

bats-core:

github.com/bats-core/b…

Bat Evaluation Process:

github.com/sstephenson…

本文首发于公众号”小米运维“,点击查看原文。

相关文章:

ORB + OPENCV

一、介绍 假如有两张人物图片&#xff0c;我们的目标是要确认这两张图片中的人物是否是同一个人。如果人来判断&#xff0c;这太简单了。但是让计算机来完成这个功能就困难重重。一种可行的方法是&#xff1a; 分别找出两张图片中的特征点描述这些特征点的属性&#xff0c;比较…

【Codeforces】967C Stairs and Elevators (二分)。

http://codeforces.com/contest/967/problem/C 从一个地方到另一个地方&#xff0c;可以选择爬楼梯或者坐电梯 &#xff0c;前提是楼梯或者电梯存在。 n 楼层数 m 每一层的房间数 s 楼梯的数量 e 电梯的数量 v 电梯的速度 第2行是s个楼梯的位置 第3行是e个电梯的位置 …

webpack 最简打包结果分析

原文链接&#xff1a;https://ssshooter.com/2019-02... 现在的 webpack 不再是入门噩梦,过去 webpack 最让人心塞的莫过于配置文件&#xff0c;而 webpack4 诞生随之而来的是无配置 webpack。 使用 webpack4&#xff0c;至少只需要安装 webpack 和 webpack cli。所以大家完全可…

orb-slam2(学习笔记)+相机

单目&#xff08;Monocular&#xff09;、双目&#xff08;Stereo&#xff09;、深度相机&#xff08;RGB-D&#xff09; 深度相机能够读取每个像素离相机的距离 &#xff0c;单目相机 只使用一个摄像头进行SLAM的做法叫做单目SLAM&#xff08;Monocular SLAM&#xff09;,结构…

如何在nuget上传自己的包+搭建自己公司的NuGet服务器(新方法)

运维相关&#xff1a;http://www.cnblogs.com/dunitian/p/4822808.html#iis 先注册一个nuget账号https://www.nuget.org/ 下载并安装一下NuGetPackageExplorer&#xff1a;https://github.com/NuGetPackageExplorer/NuGetPackageExplorer 创建一个包&#xff08;vs其实也是可以…

【Codeforces】1080C Masha and two friends (棋盘染色)

http://codeforces.com/problemset/problem/1080/C 给定一个棋盘&#xff0c;&#xff08;1&#xff0c;1&#xff09;的位置是白色&#xff0c;观察可以知道&#xff0c;如果横纵坐标之和是偶数&#xff0c;那么是白色&#xff0c;奇数的话就是黑色。 只要算出染色以后白色方…

Java多线程001——一图读懂线程与进程

本博客 猫叔的博客&#xff0c;转载请申明出处前言 本系列将由浅入深&#xff0c;学习Java并发多线程。 一图读懂线程与进程 1、一个进程可以包含一个或多个线程。&#xff08;其实你经常听到“多线程”&#xff0c;没有听过“多进程”嘛&#xff09;2、进程存在堆和方法区 3、…

TermCriteria模板类

学习写vo过程中遇到的 类功能&#xff1a;模板类&#xff0c;作为迭代算法的终止条件。 构造函数&#xff1a; TermCriteria(int type,int maxCount,double epsilon); 参数说明&#xff1a; type 迭代终止条件类型 typeTermCriteria::MAX_ITER/TermCrite…

SQL优化快速入门

最近遇到一个专门进行SQL技术优化的项目&#xff0c;对很多既有的老存储过程进行调优&#xff08;现在已经不再新增任何存储过程&#xff09;&#xff0c;因此系统的对SQL语句编写进行一次科学的学习变得很有必要。这儿将基于黄德承大神的Oracle SQL语句优化一书&#xff0c;选…

【HDU】4509 湫湫系列故事——减肥记II (区间覆盖 暴力)

http://acm.hdu.edu.cn/showproblem.php?pid4509 给出的时间段是被占用的时间&#xff0c;24h 1440 min&#xff0c;求出这些区间以外的区间长度 把00&#xff1a;00 - 23&#xff1a;59 变成0-1440 1-5都是被占用的区域&#xff0c;暴力很好理解 #include <iostream>…

Java并发编程71道面试题及答案

Java并发编程71道面试题及答案 1、在java中守护线程和本地线程区别&#xff1f; java中的线程分为两种&#xff1a;守护线程&#xff08;Daemon&#xff09;和用户线程&#xff08;User&#xff09;。 任何线程都可以设置为守护线程和用户线程&#xff0c;通过方法Thread.setDa…

USB获取图像实时处理

手写&#xff36;&#xff2f;的准备工作&#xff0c;调用&#xff35;&#xff21;&#xff22;或者本地相机获取视频图像&#xff0c;读取并保存视频。 #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "openc…

常见数据库 性能

2019独角兽企业重金招聘Python工程师标准>>> 转载于:https://my.oschina.net/u/582827/blog/778908

【Codeforces】1093C Mishka and the Last Exam

http://codeforces.com/problemset/problem/1093/C 已知b[i]求a[i]和a[n-i1]&#xff0c;n是a数组中元素的个数&#xff0c;a数组的下标从1开始 输出b[1]的时候&#xff0c;直接让a[1] 0&#xff0c;a[n] b[0] 接下来的每一组&#xff0c;先让a[i] b[i]&#xff0c;然后求…

PHP面试常考内容之Memcache和Redis(2)

你好&#xff0c;是我琉忆。继周一&#xff08;2019.2-18&#xff09;发布的“PHP面试常考内容之Memcache和Redis&#xff08;1&#xff09;”后&#xff0c;这是第二篇&#xff0c;感谢你的支持和阅读。本周&#xff08;2019.2-18至2-22&#xff09;的文章内容点为以下几点&am…

毫米波雷达、ADAS中的应用以及毫米波雷达的检测、测距、测速和角度测量

毫米波雷达的检测、测距、测速和角度测量 毫米波(Millimeter-Wave&#xff0c;缩写&#xff1a;MMW)&#xff0c;是指长度在1~10mm的电磁波&#xff0c;对应的频率范围为30~300GHz&#xff0e;根据波的传播理论&#xff0c;频率越高&#xff0c;波长越短&#xff0c;分辨率越高…

【VMC实验室】在QCloud上创建您的SQL Cluster(1)

在国内公有云厂商上搭建一套SQL Cluster的难度相信做Windows的童鞋都会很清楚&#xff0c;并非它的搭建有多少难度&#xff0c;只是很多细节需要注意。腾讯云&#xff0c;QCloud&#xff0c;为什么选择QCloud来做这个实验&#xff0c;除了QCloud是我的东家&#xff08;啊呸&…

【Codeforces】808D Array Division(前后两部分和相等)

http://codeforces.com/contest/808/problem/D 给你一个数组&#xff0c;问&#xff1a;是否可以通过移动一个数字的位置&#xff0c;求只能移动一次&#xff0c;使得这个数组前后部分的和相等&#xff0c;前后部分不一定等长 一个a数组储存数据&#xff0c;另一个b数组b[i]表…

想要确保架构目标达成?适合度函数了解一下

Paula Paul和Rosemary Wang撰写的一篇博文中介绍了适应度函数&#xff08;fitness function&#xff09;的基本概念、入门方法&#xff0c;并给出了如何验证各种架构质量的一些实例。文中提出&#xff0c;适应度函数驱动开发的方法可用于编写测定系统符合架构目标的测试&#x…

标定(二)----------双目相机与IMU联合标定(工具箱使用方法——Kalibr)

16个相机参数&#xff1a; Overview ethz-asl/kalibr is a toolbox that solves the following calibration problems: Multiple camera calibration: intrinsic and extrinsic calibration of a camera-systems with non-globally shared overlapping fields of view Cam…

【Codeforces】659B Qualifying Contest (sort)

http://codeforces.com/problemset/problem/659/B n个人&#xff0c;m个地区&#xff0c;选出每个地区分数最高的两个人 下面有n行&#xff0c;每一行的第一个数表示姓名&#xff0c;第二个数是地区的序号&#xff0c;第三个数是分数 It is guaranteed that all surnames of…

Protractor测试环境搭建

2019独角兽企业重金招聘Python工程师标准>>> 安装node.js.然后&#xff0c;在cmd下&#xff0c;进入E盘下的&#xff0c;我们自己新建的protractor文件夹下&#xff0c; npm install -g protractor 这样就会在本地安装好两个命令行工具&#xff1a;protractor和webd…

Promise和Promise的方法

&#xff08;Promise和Promise的方法&#xff09; Promise是ES6一个伟大的发明&#xff0c;他使我们从回调地狱中能够走出来。 什么是Promise 从字面上来看&#xff0c;Promise就是一个承诺。那么&#xff0c;在ES6当中&#xff0c;Promise通常用来控制异步操作。当一个异步操作…

镜头评价指标及测试方法(三)--------测量原理及3D相机调查

1.测量原理&#xff1a; 1.1、通过红外结构光(Structured Light)来测量像素距离&#xff0c;如Kinect1、Project Tango1、Intel Realsense等&#xff1b; 通过近红外激光器&#xff0c;将具有一定结构特征的光&#xff08;比如离散光斑、条纹光、编码结构光等&#xff09;投射到…

Android--Retrofit的简单使用(一)

1&#xff0c;如果不太了解retrofit的同学可以先去官网学习一下简单使用&#xff1a;http://square.github.io/retrofit/&#xff0c;这里我们以一个简单的Get请求的例子来练习一下 2&#xff0c;https://api.douban.com/v2/movie/top250?start0&count10 目标地址&#xf…

【Codeforces】920A Water The Garden(浇花)

http://codeforces.com/problemset/problem/920/A 给你花坛的数目&#xff0c;花坛都是连续的&#xff0c;某一些花坛里有水龙头&#xff0c;给出了这些有水龙头的位置 The garden from test 1. White colour denotes a garden bed without a tap, red colour — a garden be…

Work with Alexa :Echo匹配连接到Alexa

背景&#xff1a; 通过蓝牙可以让你的智能家居设备和Echo设备连接起来&#xff0c;从而达到Echo通过语音控制智能家居设备。 什么事Alexa Gadgets&#xff1f; 我的理解Alexa Gadgets是智能家居设备的一部分&#xff0c;包含硬件和软件。硬件&#xff1a;蓝牙模块&#xff1b;软…

Maven 学习Tips

2019独角兽企业重金招聘Python工程师标准>>> 使用 deploy 应该注意的地方 在项目的pom文件中增加如下节点&#xff1a;<project><distributionManagement><repository><id>releases</id><url>http://192.168.1.99:8081/nexus/c…

【Codeforces】1015B Obtaining the String(字符串 交换)

http://codeforces.com/contest/1015/problem/B n 表示 字符串的长度 然后是两个字符串&#xff0c;每一次只能交换相邻的两个&#xff0c;如果选择第i个字符的话&#xff0c;只能交换第i个和第i1个 然后输出每一次交换选定的位置 暴力&#xff0c;模拟&#xff0c;queue&am…

07 分支管理 —— Feature分支

2019独角兽企业重金招聘Python工程师标准>>> 07 分支管理 —— Feature分支 软件开发中&#xff0c;总有无穷无尽的新的功能要不断添加进来。添加一个新功能时&#xff0c;你肯定不希望因为一些实验性质的代码&#xff0c;把主分支搞乱了&#xff0c;所以&#xff0…