测试脚本案例
实例一 直接BAT调用FTP命令 ftpbat bat内容 (***大家建立bat文件不要命名为ftp bat 执行时会有问题***)
复制代码 代码如下:
ftp open lgh get sql rar bye
从图上的结果看 bat脚本直接调用xp的FTP命令是不行的 执行时H:>ftp会一直死循环 我这里的XP系统是SP 的 其它版本的 我没有作测试 如果有不同 欢迎大家留言告之 实例二 用put get上传 下载单个文件 把XP机器上H:js目录下文件flower zip上传到FTP服务器 把FTP服务器中的sql rar文件下载到XP机器上的H:JS目录 ftp get put bat内容如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo get sql rar >> %ftpfilename% echo put flower zip >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
我们来看看结果 见下面两张图 从XP系统上看 H盘的JS目录 多了个sql rar FTP服务器上的根目录多了个flower zip 这说明 刚才的脚本完成正常的执行了 达到了预期的目的
实例三 用put get上传 下载多个文件 在XP机器上把flower zip复制一次 改名为flower zip 在XP机器上把把第二次实例下载的sql rar文件删除 以免影响到本次操作 在FTP服务器上把第二次实例上传的flower zip文件删除 以免影响到本次操作 把XP机器上H:js目录下文件flower zip 和flower zip上传到FTP服务器 ftp get put many bat内容如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo put flower zip flower zip>> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
到FTP服务器上查看根目录 看flower zip与flower zip是否已成功上传 从图上看 只成功上传了flower zip文件
刚那个ftp get put many bat脚本里echo put flower zip flower zip>> %ftpfilename% flower zip是传输的最后一个文件 是不是用put时 意味着bat在处理上传时 只认最后一个文件呢 我们再多加个文件flower zip 来验证
在XP机器上把flower zip复制一次 改名为flower zip在FTP服务器上把第二次实例上传的flower zip文件删除 以免影响到本次操作
ftp get put many bat内容修改如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo put flower zip flower zip flower zip>> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
结果 还是只成功上传了flower zip 因bat双击时 执行过程会一闪而过 我们看不到执行过程 到命令行去执行下 看到底出了什么问题
命令行 执行ftp get put many bat脚本 从执行情况看 flower zip三个文件都是put的 但在传输时 却只传了flower zip 真不解 有知道的朋友吗?给点方向
再换个方式 用通配符* 试试 ftp get put many bat内容修改如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo put flower* zip >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
在FTP服务器上把上传的flower文件全部删除 以免影响到本次操作执行ftp get put many bat 结果只有flower zip文件上传成功了 呵 flower zip文件 怎么都不能上传 ???
其实用put传输多个文件 完全可用重复的方式取代 比如 ftp get put many bat内容修改如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo put flower zip >> %ftpfilename% echo put flower zip >> %ftpfilename% echo put flower zip >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
实例四 用mput mget上传 下载多个文件 在FTP服务器上删除有关flower的文件ftp mget mput many bat内容如下:
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo mput flower zip flower zip flower zip>> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
双击ftp mget mput many bat后 发现系统弹出一窗口后 就卡住了 停止不前
原因是用了mput命令 但没有用Prompt关闭交互
ftp mget mput many bat内容修改如下:
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo Prompt >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo mput flower zip flower zip flower zip>> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
再次执行ftp mget mput many bat 结果见下图
用通配符*试试在FTP服务器上删除有关flower的文件ftp mget mput many bat内容修改如下:
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo Prompt >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo mput flower* zip >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
照样成功上传有关flower* zip文件 因为结果与上一步是一样的 所以就不抓图了 实例五 用ascii在windows系统间传输非文本文件 把XP电脑上的rmb jpg通过ascii传到FTP服务器的根目录
ftp get ascii bat内容修改如下:
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo lgh >> %ftpfilename% echo >> %ftpfilename% echo ascii >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo put rmb jpg>> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
执行ftp get ascii bat后 发现rmb jpg可以正常上传 并且可以正常打开 那 这个现象与前面所以的ascii不能传输非文本东西有出入 这是怎么回会事呢 这是因为 FTP服务器是WINDOWS系统 XP电脑上的bat脚本也是在windows系统上运行的 所以bat在windows系统里用FTP传输文件 不管是用ascii 还是用binary 都是可以的 接下来我们再做一个实验 FTP服务器选centos 再测下ascii传输非文本文件问题 实例六 用ascii在windows系统与linux系统间传输非文本文件 在RHEL 位系统上建立一vsftpd服务器 上面说过redhat默认启用二进制传输 关闭了ascii码传输 所以我们还要修改一下vsftpd的配置文件 修改/etc/vsftpd/nf文件 允许客户端进行ascii传输 并重启vsftpd
把rmb jpg放到FTP服务器 大家注意下H:js目录下只有ftp getascii bat文件
ftp getascii bat文件内容修改如下
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo ftp >> %ftpfilename% echo redhat >> %ftpfilename% echo asc >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo get rmb jpg >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
执行ftp getascii bat 看结果 rmb jpg文件有下载到XP电脑里 双击这个文件 发现图像乱码 文件被破坏了 都是ascii码传输惹的祸换bin传输 测试一下在XP电脑上删除rmb jpg文件 再双击ftp getascii bat文件 去从LINUX的FTP服务器下载一个rmb jpg文件
修改ftp getascii bat 把ascii改给二进制传输
复制代码 代码如下:
@echo off set ftpfilename=autoftp cfg echo open > %ftpfilename% echo ftp >> %ftpfilename% echo redhat >> %ftpfilename% echo bin >> %ftpfilename% echo lcd h:js >> %ftpfilename% echo get rmb jpg >> %ftpfilename% echo bye >> %ftpfilename% ftp s: %ftpfilename% del %ftpfilename%
结果 文件正常下载 图像也显示正常 lishixin/Article/program/qrs/201401/30223
Ⅱ Python实现性能自动化测试竟然如此简单
一、思考❓❔
1.什么是性能自动化测试?
2.Python中的性能自动化测试库?
locust库
二、基础操作
1.安装locust
安装成功之后,在cmd控制台将会新增一条命令,可输入如下命令查看:
2.基本用法
三、综合案例演练
1.编写自动化测试脚本
2.使用命令行运行
3.打开web ui界面进行配置
设置并发用户数为10,每5秒创建一个用户
压测过程截图
美轮美奂的压测报告
压测失败详情
下载压测统计数据
下载的压测统计数据csv文件
六、总结
出处:https://www.cnblogs.com/keyou1/
Ⅲ Bash 脚本进阶,经典用法及其案例
前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像我当初刚开始学一样,感觉会写脚本的都是大神。虽然复杂的脚本是很烧脑,但是,当我们熟练的掌握了其中的用法与技巧,再多加练习,总有一天也会成为得心应手的脚本大神。脚本在生产中的作用,想必我我不说,大家也都知道,脚本写的6,可以省下很多复杂的操作,减轻自己的工作压力。好了,废话不多说,接下来,就是Bash脚本的用法展示。
(1)用法格式
if 判断条件 1 ; then
条件为真的分支代码
elif 判断条件 2 ; then
条件为真的分支代码
elif 判断条件 3 ; then
条件为真的分支代码
else
以上条件都为假的分支代码
fi
逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if。
(2)经典案例:
① 判断年纪
分析:请输入年纪,先判断输入的是否含有除数字以外的字符,有,就报错;没有,继续判断是否小于150,是否大于18。
② 判断分数
分析:请输入成绩,先判断输入的是否含有除数字以外的字符,有,就报错;没有,继续判断是否大于100,是否大于85,是否大于60。
(1)用法格式
case $name in;
PART1)
cmd
;;
PART2)
cmd
;;
*)
cmd
;;
esac
注意:case 支持glob 风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[] :指定范围内的任意单个字符
a|b: a 或b
(2)案例:
判断yes or no
分析:请输入yes or no,回答Y/y、yes各种大小写组合为yes;回答N/n、No各种大小写组合为no。
(1)用法格式
① for name in 列表 ;do
循环体
done
② for (( exp1; exp2; exp3 )) ;do
cmd
done
exp1只执行一次,相当于在for里嵌了while
③ 执行机制:依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
列表的表示方法,可以glob 通配符,如{1..10} 、*.sh ;也可以变量引用,如: `seq 1 $name`
(2)案例
① 求出(1+2+...+n)的总和
分析:sum初始值为0,请输入一个数,先判断输入的是否含有除数字以外的字符,有,就报错;没有判断是否为0,不为0进入for循环,i的范围为1~输入的数,每次的循环为sum=sum+i,循环结束,最后输出sum的值。
② 求出(1+2+...+100)的总和
分析:i=1,num=0;当i<=100,进入循环,若i 2取余=1,则sum=sum+i,i=i+1。
(1)用法格式
while 循环控制条件 ;do
循环
done
循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true” ,则执行一次循环;直到条件测试状态为“false” 终止循环
(2)特殊用法(遍历文件的每一行):while read line; do控制变量初始化循环体done < /PATH/FROM/SOMEFILE或 cat /PATH/FROM/SOMEFILE | while read line; do循环体done依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
(3)案例:
① 100以内所有正奇数之和
分析:sum初始值为0,i的初始值为1;请输入一个数,先判断输入的是否含有除数字以外的字符,有,就报错;没有当i<100时,进入循环,判断 i 2取余 是否不为0,不为0时为奇数,sum=sum+i,i+1,为0,i+1;循环结束,最后输出sum的值。
(1)用法
unitl 循环条件 ;do
循环
done
进入条件:循环条件为true ;退出条件:循环条件为false;刚好 和while相反 ,所以不常用,用while就行。
(2)案例
监控xiaoming用户,登录就杀死
分析:每隔0.5秒扫描,直到发现xiaoming用户登录,杀死这个进程,退出脚本,用于监控用户登录。
(1)用法
select variable in list
do
循环体命令
done
① select 循环主要用于创建菜单,按数字顺序排列的示菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入
② 用户输入菜单列表中的某个数字,执行相应的命令
③ 用户输入被保存在内置变量 REPLY 中
④ select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 按 命令终止脚本。也可以按 ctrl+c退出循环
⑤ select 和 经常和 case 联合使用
⑥ 与for循环类似,可以省略 in list, 此时使用位置参量
(2)案例:
生成菜单,并显示选中的价钱
分析:PS3是select的提示符,自动生成菜单,选择5break退出循环。
(1)语法
continue [N]:提前结束 第N层的本轮 循环,而直接进入下一轮判断;最内层为第1层
break [N]:提前结束 第N层 循环,最内侧为第1层
例:while CONDTITON1; doCMD1if CONDITION2; thencontinue / breakfiCMD2done (2)案例:
① 求(1+3+...+49+53+...+100)的和
分析:做1+2+...+100的循环,当i=51时,跳过这次循环,但是继续整个循环,结果为:sum=2449
② 求(1+3+...+49)的和
分析:做1+2+...+100的循环,当i=51时,跳出整个循环,结果为:sum=625
(1)作用
用于将参数列表list左移指定次数,最左端的那个参数就从列表中删除,其后边的参数继续进入循环
(2)案例:
① 创建指定的多个用户
分析:如果没有输入参数(参数的总数为0),提示错误并退出;反之,进入循环;若第一个参数不为空字符,则创建以第一个参数为名的用户,并移除第一个参数,将紧跟的参数左移作为第一个参数,直到没有第一个参数,退出。
② 打印直角三角形的字符
true 永远返回成功结果
: null command ,什么也不干,返回成功结果
false 永远返回错误结果
创建无限循环
while true ;do
循环体
done
(1)用法
for name in 列表 ;do
{
循环体
}&
done
wait
(2)实例:
搜寻自己指定ip(子网掩码为24的)的网段中,UP的ip地址
分析:请输入一个IP地址例192.168.37.234,如果格式不是0.0.0.0 则报错退出;正确则进入循环,IP变量的值为192.168.37. i的范围为1-254,并行ping 192.168.37.1-154,ping通就输出此IP为UP。直到循环结束。
trap ' 触发指令' 信号,自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作
trap '' 信号,忽略信号的操作
trap '-' 信号,恢复原信号的操作
trap -p ,列出自定义信号操作
信号可以3种表达方法:信号的数字2、全名SIGINT、缩写INT
1) SIGHUP: 无须关闭进程而让其重读配置文件
2) SIGINT: 中止正在运行的进程;相当于Ctrl+c
3) SIGQUIT: 相当于ctrl+
9) SIGKILL: 强制杀死正在运行的进程
15) SIGTERM :终止正在运行的进程(默认为15)
18) SIGCONT :继续运行
19) SIGSTOP :后台休眠
9 信号,强制杀死,捕获不住
① 打印0-9,ctrl+c不能终止
分析:i=0,当i<10,每休眠1秒,i+1,捕获2信号,并执行echo press ctrl+c
② 打印0-3,ctrl+c不能终止,3之后恢复,能终止
分析:i=0,当i3时,解除捕获2信号。
1、生成随机字符 cat /dev/urandom
生成8个随机大小写字母或数字 cat /dev/urandom |tr -dc [:alnum:] |head -c 8
2、生成随机数 echo $RANDOM
确定范围 echo $[RANDOM%7] 随机7个数(0-6)
echo $[$[RANDOM%7]+31] 随机7个数(31-37)
3、echo打印颜色字
echo -e "33[31malong33[0m" 显示红色along
echo -e "33[1;31malong33[0m" 高亮显示红色along
echo -e "33[41malong33[0m" 显示背景色为红色的along
echo -e "33[31;5malong33[0m" 显示闪烁的红色along
color=$[$[RANDOM%7]+31]
echo -ne "33[1;${color};5m*33[0m" 显示闪烁的随机色along
Ⅳ Python3脚本传参实战(2个方法3个传参列表的案例)
在一些测试平台对接时或者用例执行时,或多或少会用到Python脚本传参的问题。
test.py脚本
#!/usr/bin/python3
import sys
print ('参数个数为:', len(sys.argv), '个参数。')
print ('参数列表:', str(sys.argv))
print ('脚本名:', str(sys.argv[0]))
print ('第一个参数:', sys.argv[1])
执行python3 test.py arg1 arg2 arg3
参数个数为: 4 个参数。
参数列表: ['test.py', 'arg1', 'arg2', 'arg3']
脚本名: test.py
第一个参数: arg1
test.py脚本
#!/usr/bin/python3
import argparse
# 生成了一个命令行参数的对象
parser = argparse.ArgumentParser(description='Test for argparse')
parser.add_argument('--name', '-n', help='name属性,非必要参数')
parser.add_argument('--year', '-y', help='year 属性,非必要参数,但有默认值', default=2017)
parser.add_argument('--body', '-b', help='body属性,必要参数', required=True)
args = parser.parse_args()
print (args.year, args.name, args.body)
查看帮助python3 test.py --help
usage: test.py [-h] [--name NAME] [--year YEAR] --body BODY
Test for argparse
optional arguments:
-h, --help show this help message and exit
--name或-n NAME name属性,非必要参数
--year或-y YEAR year属性,非必要参数,但有默认值
--body或-b BODY body 属性,必要参数
执行python3 test.py --year 2021 -n robot --body "are you ok?"
2021 robot are you ok?
以方法2中的test.py脚本为例
python3 test.py --year 2021 --body [\"test\", \"robot\",\"boy\" ]
2021 ["test", "robot", "boy" ]
以方法1中的test.py脚本为例
python3 test.py [\"test\", \"robot\",\"boy\" ]
参数个数为: 2个参数。
参数列表: ['test.py', '[\"test\", \"robot\", \"boy\" ]']
脚本名: test.py
第一个参数: ["test", "robot", "boy" ]
其实此时传入的第一个参数是一个字符,需要转换为列表。
import json
json.loads(sys.argv[1])
test_arg.py脚本
#!/usr/bin/python3
import argparse
import os
# 生成了一个命令行参数的对象
parser = argparse.ArgumentParser(description='Test for argparse')
parser.add_argument('--body', '-b', help='body属性,必要参数', required=True)
args = parser.parse_args()
print (args.body)
command=python3 + ' ' + test_sys.py+ ' ' + args.body
print (command)
str=('command')
result=os.system(str)
test_sys.py脚本
#!/usr/bin/python3
import sys
import json
print ('第一个参数:', sys.argv[1])
print ('列表:', json.loads(sys.argv[1]))
执行python3 test_arg.py --body [\"test\", \"robot\",\"boy\" ]
python3 test_sys.py ["test", "robot", "boy" ]
test_sys.py执行报错,转json失败。
还记得我们案例2中,脚本的传入指定参数和实际传入参数嘛?
test_arg.py脚本我们稍微优化下,在传参前先字符替换下。
["test", "robot", "boy" ]转换为[\"test\", \"robot\",\"boy\" ]即可。
command.replace(' " ' , r ' \" ') 添加到command=之后,再次运行看看呢?
Ⅳ 如何使用Bash Shell脚本进行功能测试
在本文中,Angel Rivera 将说明如何运用 Bash shell 脚本通过行命令来执行 Linux 应用程序的功能测试。由于此脚本依赖于命令行的返回码,因而您不能将这种方法运用于 GUI 应用程序 功能测试是开发周期的一个阶段,在这个阶段中将测试软件应用程序以确保软件的函数如预期的那样,同时能正确处理代码中错误。此项工作通常在单个模块的单元测试结束之后,在负载/重压条件下整个产品的系统测试之前进行的。 市场上有许多测试工具提供了有助于功能测试的功能。然而,首先要获取它们,然后再安装、配置,这将占用您宝贵的时间和精力。Bash 可以帮您免去这些烦琐的事从而可以加快测试的进程。 使用Bash shell 脚本进行功能测试的优点在于: Bash shell 脚本已经在 Linux 系统中安装和配置好了。不必再花时间准备它。 可以使用由 Linux 提供的文本编辑器如 vi 创建和修改 Bash shell 脚本。不需要再为创建测试程序而获取专门的工具。 如果已经知道了如何开发 Bourne 或 Korn shell 脚本,那对于如何运用 Bash shell 脚本已经足够了。对您来说,学习曲线已不存在了。 Bash shell 提供了大量的编程构造用于开发从非常简单到中等复杂的脚本。 将脚本从 Korn 移植到 Bash 时的建议 如果已有现成的 Korn shell 脚本,而想要将它们移植到 Bash,就需要考虑下列情况: Korn 的 "print" 命令在 Bash 中不能使用;而是改为使用 "echo" 命令。 需要将脚本的第一行: #!/usr/bin/ksh 修改成: #!/bin/bash 创建Bash shell 脚本进行功能测试 这些基本的步骤和建议适用于许多在 Linux 上运行的客户机/服务器应用程序。 记录运行脚本的先决条件和主要步骤 将操作分成若干个逻辑组 基于一般方案制定执行步骤 在每个 shell 脚本中提供注释和说明 做一个初始备份以创建基准线 检查输入参数和环境变量 尝试提供 "usuage" 反馈 尝试提供一个“安静”的运行模式 当出现错误时,提供一个函数终止脚本 如可能,提供可以执行单个任务的函数 当显示正在生成的输出时,捕获每个脚本的输出 在每个脚本内,捕获每个行命令的返回码 计算失败事务的次数 在输出文件中,突出显示错误消息,以便于标识 如有可能,“实时”生成文件 在执行脚本的过程中提供反馈 提供脚本执行的摘要 提供一个容易解释的输出文件 如有可能,提供清除脚本及返回基准线的方法 下面详细讲述了每一条建议以及用于说明问题的脚本。若要下载此脚本,请参阅本文后面的 参考资料部分。 1. 记录运行脚本的先决条件和主要步骤 记录,尤其是以有自述标题的单个文件(例如 "README-testing.txt")记录功能测试的主要想法是很重要的,包括,如先决条件、服务器和客户机的设置、脚本遵循的整个(或详细的)步骤、如何检查脚本的成功/失败、如何执行清除和重新启动测试。 2. 将操作分成若干个逻辑组 如果仅仅执行数量非常少的操作,可以将它们全部放在一个简单的 shell 脚本中。 但是,如果需要执行一些数量很多的操作,那最好是将它们分成若干个逻辑集合,例如将一些服务器操作放在一个文件而将客户机操作放在在另一个文件中。通过这种方法,划分适当的颗粒度来执行测试和维护测试。 3. 基于一般方案制定执行步骤 一旦决定对操作进行分组,需要根据一般方案考虑执行操作的步骤。此想法是模拟实际生活中最终用户的情形。作为一个总体原则,只需集中测试 80% 最常调用函数的 20% 用法即可。 例如,假设应用程序要求 3 个测试组以某个特定的顺序排列。每个测试组可以放在一个带有自我描述文件名(如果可能)的文件中,并用号码来帮助识别每个文件的顺序,例如: 1. fvt-setup-1: To perform initial setup. 2. fvt-server-2: To perform server commands. 3. fvt-client-3: To perform client commands. 4. fvt-cleanup: To cleanup the temporary files, in order to prepare for the repetition of the above test cases. 4. 在每个 shell 脚本中提供注释和说明 在每个 shell 脚本的头文件中提供相关的注释和说明是一个良好的编码习惯。这样的话,当另一个测试者运行该脚本时,测试者就能清楚地了解每个脚本中测试的范围、所有先决条件和警告。 下面是一个 Bash 脚本 "test-bucket-1" 的示例 。 #!/bin/bash # # Name: test-bucket-1 # # Purpose: # Performs the test-bucket number 1 for Proct X. # (Actually, this is a sample shell script, # which invokes some system commands # to illustrate how to construct a Bash script) # # Notes: # 1) The environment variable TEST_VAR must be set # (as an example). # 2) To invoke this shell script and redirect standard # output and standard error to a file (such as # test-bucket-1.out) do the following (the -s flag # is "silent mode" to avoid prompts to the user): # # ./test-bucket-1 -s 2>&1 | tee test-bucket-1.out # # Return codes: # 0 = All commands were successful # 1 = At least one command failed, see the output file # and search for the keyword "ERROR". # ######################################################## 5. 做一个初始备份以创建基准线 您可能需要多次执行功能测试。第一次运行它时,也许会找到脚本或进程中的一些错误。因而,为了避免因从头重新创建服务器环境而浪费大量时间 -- 特别是如果涉及到数据库 -- 您在测试之前或许想做个备份。 在运行完功能测试之后,就可以从备份中恢复服务器了,同时也为下一轮测试做好了准备。 6. 检查输入参数和环境变量 最好校验一下输入参数,并检查环境变量是否设置正确。如果有问题,显示问题的原因及其修复方法,然后终止脚本。 当测试者准备运行脚本,而此时如果没有正确设置脚本所调用的环境变量,但由于发现及时,终止了脚本,那测试者会相当感谢。没有人喜欢等待脚本执行了很久却发现没有正确设置变量。 # -------------------------------------------- # Main routine for performing the test bucket # -------------------------------------------- CALLER=`basename $0` # The Caller name SILENT="no" # User wants prompts let "errorCounter = 0" # ---------------------------------- # Handle keyword parameters (flags). # ---------------------------------- # For more sophisticated usage of getopt in Linux, # see the samples file: /usr/lib/getopt/parse.bash TEMP=`getopt hs $*` if [ $? != 0 ] then echo "$CALLER: Unknown flag(s)" usage fi # Note quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true do case "$1" in -h) usage "HELP"; shift;; # Help requested -s) SILENT="yes"; shift;; # Prompt not needed --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done # ------------------------------------------------ # The following environment variables must be set # ------------------------------------------------ if [ -z "$TEST_VAR" ] then echo "Environment variable TEST_VAR is not set." usage fi 关于此脚本的说明如下: 使用语句 CALLER=`basename $0` 可以得到正在运行的脚本名称。这样的话,无须在脚本中硬编码脚本名称。因此当复制脚本时,采用新派生的脚本可以减少工作量。 调用脚本时,语句 TEMP=`getopt hs $*` 用于得到输入变量(例如 -h 代表帮助,-s 代表安静模式)。 语句[ -z "$X" ] 和 echo "The environment variable X is not set." 以及 usage 都是用于检测字符串是否为空 (-z),如果为空,随后就执行 echo 语句以显示未设置字符串并调用下面要讨论的 "usage" 函数。 若脚本未使用标志,可以使用变量 "$#",它可以返回正在传递到脚本的变量数量。 7. 尝试提供“usage”反馈 脚本中使用 "usage" 语句是个好主意,它用来说明如何使用脚本。 # ---------------------------- # Subroutine to echo the usage # ---------------------------- usage() { echo "USAGE: $CALLER [-h] [-s]" echo "WHERE: -h = help " echo " -s = silent (no prompts)" echo "PREREQUISITES:" echo "* The environment variable TEST_VAR must be set," echo "* such as: " echo " export TEST_VAR=1" echo "$CALLER: exiting now with rc=1." exit 1 } 调用脚本时,使用“-h”标志可以调用 "usage" 语句,如下所示: ./test-bucket-1 -h 8. 尝试使用“安静”的运行模式 您或许想让脚本有两种运行模式: 在"verbose" 模式(您也许想将此作为缺省值)中提示用户输入值,或者只需按下 Enter 继续运行。 在"silent" 模式中将不提示用户输入数据。 下列摘录说明了在安静模式下运用所调用标志 "-s" 来运行脚本: # ------------------------------------------------- # Everything seems OK, prompt for confirmation # ------------------------------------------------- if [ "$SILENT" = "yes" ] then RESPONSE="y" else echo "The $CALLER will be performed." echo "Do you wish to proceed [y or n]? " read RESPONSE # Wait for response [ -z "$RESPONSE" ] && RESPONSE="n" fi case "$RESPONSE" in [yY]|[yY][eE]|[yY][eE][sS]) ;; *) echo "$CALLER terminated with rc=1." exit 1 ;; esac 9. 当出现错误时,提供一个函数终止脚本 遇到严重错误时,提供一个中心函数以终止运行的脚本不失为一个好主意。此函数还可提供附加的说明,用于指导在此情况下应做些什么: # ---------------------------------- # Subroutine to terminate abnormally # ---------------------------------- terminate() { echo "The execution of $CALLER was not successful." echo "$CALLER terminated, exiting now with rc=1." dateTest=`date` echo "End of testing at: $dateTest" echo "" exit 1 } 10. 如有可能,提供可以执行简单任务的函数 例如,不使用许多很长的行命令,如: # -------------------------------------------------- echo "" echo "Creating Access lists..." # -------------------------------------------------- Access -create -component Development -login ted -authority plead -verbose if [ $? -ne 0 ] then echo "ERROR found in Access -create -component Development -login ted -authority plead" let "errorCounter = errorCounter + 1" fi Access -create -component Development -login pat -authority general -verbose if [ $? -ne 0 ] then echo "ERROR found in Access -create -component Development -login pat -authority general" let "errorCounter = errorCounter + 1" fi Access -create -component Development -login jim -authority general -verbose if [ $? -ne 0 ] then echo "ERROR found in Access -create -component Development -login jim -authority general" let "errorCounter = errorCounter + 1" fi ……而是创建一个如下所示的函数,此函数也可以处理返回码,如果有必要,还可以增加错误计数器: CreateAccess() { Access -create -component $1 -login $2 -authority $3 -verbose if [ $? -ne 0 ] then echo "ERROR found in Access -create -component $1 -login $2 -authority $3" let "errorCounter = errorCounter + 1" fi } ……然后,以易读和易扩展的方式调用此函数: # ------------------------------------------- echo "" echo "Creating Access lists..." # ------------------------------------------- CreateAccess Development ted projectlead CreateAccess Development pat general CreateAccess Development jim general 11. 当显示正在生成的输出时,捕获每个脚本的输出 如果脚本不能自动地将输出发送到文件的话,可以利用 Bash shell 的一些函数来捕获所执行脚本的输出,如: ./test-bucket-1 -s 2>&1 | tee test-bucket-1.out 让我们来分析上面的命令: "2>&1" 命令: 使用"2>&1" 将标准错误重定向到标准输出。字符串 "2>&1" 表明任何错误都应送到标准输出,即 UNIX/Linux 下 2 的文件标识代表标准错误,而 1 的文件标识代表标准输出。如果不用此字符串,那么所捕捉到的仅仅是正确的信息,错误信息会被忽略。 管道"|" 和 "tee" 命令: UNIX/Linux 进程和简单的管道概念很相似。既然这样,可以做一个管道将期望脚本的输出作为管道的输入。下一个要决定的是如何处理管道所输出的内容。在这种情况下,我们会将它捕获到输出文件中,在此示例中将之称为 "test-bucket-1.out"。 但是,除了要捕获到输出结果外,我们还想监视脚本运行时产生的输出。为达到此目的,我们连接允许两件事同时进行的 "tee" (T- 形管道):将输出结果放在文件中同时将输出结果显示在屏幕上。其管道类似于: process --> T ---> output file | V screen 如果 只 想捕获输出结果而不想在屏幕上看到输出结果,那可以忽略多余的管道: ./test-bucket-1 -s 2>&1 > test-bucket-1.out 假若这样,相类似的管道如下: process --> output file 12. 在每个脚本内,捕获每个行命令所返回码 决定功能测试成功还是失败的一种方法是计算已失败行命令的数量,即返回码不是 0。变量 "$?" 提供最近所调用命令的返回码;在下面的示例中,它提供了执行 "ls" 命令的返回码。 # ------------------------------------------- # The commands are called in a subroutine # so that return code can be # checked for possible errors. # ------------------------------------------- ListFile() { echo "ls -al $1" ls -al $1 if [ $? -ne 0 ] then echo "ERROR found in: ls -al $1" let "errorCounter = errorCounter + 1" fi } 13. 记录失败事务的次数 在功能测试中决定其成功或失败的一个方法是计算返回值不是 0 的行命令数量。但是,从我个人的经验而言,我习惯于在我的 Bash shell 脚本中仅使用字符串而不是整数。在我所参考的手册中没有清楚地说明如何使用整数,这就是我为什么想在此就关于如何使用整数和计算错误(行命令失败)数量的方面多展开讲的原因: 首先,需要按如下方式对计数器变量进行初始化: let "errorCounter = 0" 然后,发出行命令并使用 $? 变量捕获返回码。如果返回码不是 0,那么计数器增加 1(见蓝色粗体语句): ListFile() { echo "ls -al $1" ls -al $1 if [ $? -ne 0 ] then echo "ERROR found in: ls -al $1" let "errorCounter = errorCounter + 1" fi } 顺便说一下,与其它变量一样,可以使用 "echo" 显示整数变量。 14. 在输出文件中,为了容易标识,突出显示错误消息 当遇到错误(或失败的事务)时,除了错误计数器的数量会增加外,最好标识出此处有错。较理想的做法是,字符串有一个如 ERROR 或与之相似的子串(见蓝色粗体的语句),这个子串允许测试者很快地在输出文件中查找到错误。此输出文件可能很大,而且它对于迅速找到错误非常重要。 ListFile() { echo "ls -al $1" ls -al $1 if [ $? -ne 0 ] then echo "ERROR found in: ls -al $1" let "errorCounter = errorCounter + 1" fi } 15. 如有可能,“实时”生成文件 在某些情况下,有必要处理应用程序使用的文件。可以使用现有文件,也可以在脚本中添加语句来创建文件。如果要使用的文件很长,那最好将其作为独立的实体。如果文件很小而且内容简单或不相关(重要的一点是文本文件而不考虑它的内容),那就可以决定“实时”创建这些临时文件。 下面几行代码显示如何“实时”创建临时文件: cd $HOME/fvt echo "Creating file softtar.c" echo "Subject: This is softtar.c" > softtar.c echo "This is line 2 of the file" >> softtar.c 第一个 echo 语句使用单个的 > 强行创建新文件。第二个 echo 语句使用两个 >> 将数据附加到现有文件的后面。顺便说一下,如果该文件不存在,那么会创建一个文件。 16. 在执行脚本的过程中提供反馈 最好在脚本中包含 echo 语句以表明它执行的逻辑进展状况。可以添加一些能迅速表明输出目的的语句。 如果脚本要花费一些时间执行,那或许应在执行脚本的开始和结束的地方打印时间。这样可以计算出所花费的时间。 在脚本样本中,一些提供进展说明的 echo 语句如下所示: # -------------------------------------------- echo "Subject: Proct X, FVT testing" dateTest=`date` echo "Begin testing at: $dateTest" echo "" echo "Testcase: $CALLER" echo "" # -------------------------------------------- # -------------------------------------------- echo "" echo "Listing files..." # -------------------------------------------- # The following file should be listed: ListFile $HOME/.profile ... # -------------------------------------------- echo "" echo "Creating file 1" # -------------------------------------------- 17. 提供脚本执行的摘要 如果正在计算错误或失败事务的次数,那最好表明是否有错误。此方法使得测试者在看到输出文件的最后能迅速地辨认出是否存在错误。 在下面的脚本示例中,代码语句提供了上述脚本的执行摘要: # -------------- # Exit # -------------- if [ $errorCounter -ne 0 ] then echo "" echo "*** $errorCounter ERRORS found ring ***" echo "*** the execution of this test case. ***" terminate else echo "" echo "*** Yeah! No errors were found ring ***" echo "*** the execution of this test case. Yeah! ***" fi echo "" echo "$CALLER complete." echo "" dateTest=`date` echo "End of testing at: $dateTest" echo "" exit 0 # end of file 18. 提供一个容易解释的输出文件 在脚本生成的实际输出中提供一些关键信息是非常有用的。那样,测试者就可以很容易地确定正在查看的文件是否与自己所做的相关以及它是否是当前产生的。附加的时间戳记对于是否是当前状态是很重要的。摘要报告对于确定是否有错误也是很有帮助的;如果有错误,那么测试者就必须搜索指定的关键字,例如 ERROR,并确认出个别失败的事务。 以下是一段输出文件样本的片段: Subject: CMVC 2.3.1, FVT testing, Common, Part 1 Begin testing at: Tue Apr 18 12:50:55 EDT 2000 Database: DB2 Family: cmpc3db2 Testcase: fvt-common-1 Creating Users... User pat was created successfully. ... Well done! No errors were found ring the execution of this test case :) fvt-common-1 complete. End of testing at: Tue Apr 18 12:56:33 EDT 2000 当遇到错误时输出文件最后部分的示例如下所示: ERROR found in Report -view DefectView *** 1 ERRORS found ring the execution of this test case. *** The populate action for the CMVC family was not successful. Recreating the family may be necessary before running fvt-client-3 again, that is, you must use 'rmdb', 'rmfamily', 'mkfamily' and 'mkdb -d', then issue: fvt-common-1 and optionally, fvt-server-2. fvt-client-3 terminated, exiting now with rc=1. End of testing at: Wed Jan 24 17:06:06 EST 2001 19. 如有可能,提供清除脚本及返回基准线的方法 测试脚本可以生成临时文件;假若这样,最好能让脚本删除所有临时文件。这就会避免由于测试者也许没有删除所有临时文件而引起的错误,更糟糕的是将所需要的文件当作临时文件而删除了。 运行功能测试的 Bash shell 脚本 本节描述如何运用 Bash shell 脚本进行功能测试。假设您已经执行了在前面部分中所述步骤。 设置必要的环境变量 根据需要在 .profile 中或手工指定下列环境变量。该变量用于说明在脚本中如何处理,所需环境变量的验证必须在脚本执行前定义。 export TEST_VAR=1 将Bash shell 脚本复制到正确的目录下 Bash shell 脚本和相关文件需要复制到要进行功能测试的用户标识的目录结构下。 登录进某个帐户。您应该在主目录下。假设它是 /home/tester。 为测试案例创建目录: mkdir fvt 复制Bash shell 脚本和相关文件。获取压缩文件(请参阅 参考资料 )并将其放在 $HOME 下。然后将其按下列方式解压: unzip trfvtbash.zip 为了执行这个文件,更改文件的许可权: chmod u+x * 更改名称以除去文件的后缀: mv test-bucket-1.bash test-bucket-1 运行脚本 执行下列步骤以运行脚本: 以测试者的用户标识登录 更改目录至所复制脚本的位置: cd $HOME/fvt 从$HOME/fvt 运行脚本: ./test-bucket-1 -s 2>&1 | tee test-bucket-1.out 看一下输出文件 "test-bucket-1.out" 的尾部并查看摘要报告的结论。 参考资料 您可以参阅本文在 developerWorks 全球站点上的 英文原文. 下载trfvtbash.zip,它包含本文所引用的样本代码和工具。该工具在以后有可能会更新。 尝试用 Info-ZIP 软件 解开该文件。由于该工具很常用,推荐您最好将解压和压缩工具的目录放至 PATH 中,这样该机器上的所有用户都可以使用这个工具。 如何解压该文件: 为了查看压缩文件中的内容(实际上并没有解包和解压缩该文件),用: unzip -l trfvtbash.zip 命令。(T002)