SHELL实现自动化测试框架
文章目录
- SHELL实现自动化测试框架
- 相关术语
- 背景
- 方案
- 设计
- 用例模块(case)
- 方法封装模块(method)
- 启动测试模块(run_repor)
- 关键技术
- 初始化功能的实现
- 断言功能的实现
- 测试执行功能的实现
- 测试报告功能的实现
- 实验验证
- 小结
相关术语
缩写 | 全称 | 描述 |
---|
SAT | Shell Automated Test | 使用Shell实现的自动化测试 |
背景
用以下功能用例举例
用例标题 | 步骤 | 预期 |
基础命令:验证which基础命令功能正确 | 1、在命令行输入:which bash | 1、输出:/usr/bin/bash |
2、在命令行输入:which ls whereis cp | 2、输出:/usr/bin/ls /usr/bin/whereis /usr/bin/cp |
手工测试,我们要执行该用例需进行4个步骤:
- 执行步骤1:命令行中输入命令
which bash
- 验证步骤1:查看步骤1输出结果,验证结果与用例中预期是否一致
- 执行步骤2:命令行中输入命令
which ls whereis cp
- 验证步骤2:查看步骤2输出结果,验证结果与用例中预期是否一致
模拟命令行中测试实例:
mars@mars-PC:~$ which bash
/usr/bin/bash
mars@mars-PC:~$ which ls whereis cp
/usr/bin/ls
/usr/bin/whereis
/usr/bin/cp
若从人工执行转换为自动化执行:自动执行命令、自动验证输出结果、生成测试报告,这样除了在全量测试时减少巨大的工作量,还能在回归测试、边缘测试时执行多覆盖大部分测试范围。
方案
实现该自动化方案,这里选择使用Shell
来实现。Shell
是一个命令解释器,它不仅是Linux操作系统内核与用户之间的绝缘层(俗称壳),同时也是一种功能相当强大的编程语言,可直接执行linux系统命令,它类似于DOS下的cmd.exe。
该方案除了Shell以外也可使用其他语言实现,比如Python,但是Python只能通过os、subprocess库来调用linux系统命令,不像Shell可直接执行系统命令,在脚本的编写和调式都不如Shell简洁、方便,所以最终方案的实现为Shell。这里对该技术方案命名为SAT
方便后续说明使用。
使用场景【查询xx应用进程状态】的Shell、Python代码作为对比:
import subprocess
ps_state=subprocess.run('ps aux|grep -v grep|grep -q xx', shell=True).returncode
print(ps_state)
ps aux|grep -v grep|grep -q xx
echo $?
通过以上对比可发现,实现一个相同的功能,Shell编写的代码要更为直接、简洁,命令越复杂这个优势越明显。
设计
SAT
是一个简单的自动化测试框架,主要实现命令行用例的自动执行并输出测试报告,体现出用例的执行情况,可快速对失败用例进行定位。总体可以划分为下面几个模块:
-
用例模块(case):存放转换为自动化测试用例的代码,最小单位为函数,该框架支持多个用例模块文件。
-
方法封装模块(method):存放一些公用方法函数,比如:断言、测试报告等。
-
启动测试模块(run_repor):存放启动测试的主代码,对用例模块文件进行批量处理并生成测试报告。
-
SAT目录结构如下:
SAT
├── case
│ ├── case_a.sh
│ └── case_b.sh
├── method
│ ├── assertion.sh
│ └── other.sh
├── report
│ ├── report_0817231130
│ └── report_0819115441
└── run_report.sh
-
SAT框架运行流程图如下:
用例模块(case)
实际项目中每个人负责的模块与用例不同,所以自动化测试用例需要自己编写负责部分,不像其他模块中的代码都是公用的,那么在编写格式上需要做统一的约定:
- 用例模块文件命名统一,测试人员A、B的用例模块文件:case_a.sh、case_b.sh。
- 测试用例最小单位统一:每一条测试用例为一条函数,通过函数来管理用例。
- 用例函数命名统一,测试人员A的第1、2条用例:test_a1(){}、test_a2(){}。
- 用例函数元素统一,需要包含变量:title、case_id、断言函数。
格式统一之后,每人完成自己部分的用例文件,在启动测试时只要汇总全部用例模块文件,即可完成所有人的测试用例执行。
以下为测试人员A的用例模块文件 “case_a.sh” 部分内容:
#! /bin/bash
test_a1(){
title="检查内核启动信息"
case_id=xxxxx
a="error|fail|warning|call\ trace"
b=`sudo dmesg`
assertNoIn "${a}" "${b}"
}
test_a2(){
pass
}
方法封装模块(method)
该模块主要用于存放公共方法函数,集中管理方便后期维护,封装的函数主要实现以下功能:
- 用例断言:判断用例执行结果与预期是否一致,给出对应输出结果。
- 用例处理:批量处理不同的用例模块文件:执行不同的用例模块文件,输出用例执行结果。
- 用例统计:统计用例执行的数据:统计执行用例数量、通过用例数量、失败用例数量、失败用例编号。
- 测试报告:结合以上全部内容输出本地文档,方便测试结果归档保存。
通过以上公共方法函数的封装,其他模块直接调用即可,代码更为清晰简洁,并减少冗余。
启动测试模块(run_repor)
该模块为执行测试的主模块,主要是对测试开始前环境做初始化并运行测试,主要包含:
-
模块初始化:导入方法模块;根据对用例模块文件的分析,导入对应的模块文件。
-
变量初始化:针对一些数据统计相关的函数做初始化赋值:用例数量、用例通过/失败数量、定义数组变量等。
-
运行测试:调用测试执行函数、测试报告生成函数、提示用户测试报告生成路径。
关键技术
这里主要选取了部分关键功能,其他部分则不细说了,针对这部分功能说明通过Shell是如何的实现,功能如下:
初始化功能的实现
该功能是为后续测试提供良好的运行环境,主要分为两部分:
断言功能的实现
该功能实现的是在每一条用例执行之后,对用例执行结果与预期结果对比,判断用例执行结果为通过、失败,并且对结果进行输出;与此同时也参与了一些数据收集工作,递增通过/失败/执行用例数量。
断言对比的方法多种多样,这里拿部分举例,详情见下方代码:
assertEqual(){
if [ "${1}" = "${2}" ]
then
r="pass"
else
r="fail"
fail_id[${fail}]=${case_id}
fi
case_pf
}
assertNoIn(){
result=`echo "${2}"|grep -E "${1}"`
if [ "${result}" ]
then
r="fail"
fail_id[${fail}]=${case_id}
else
r="pass"
fi
case_pf
}
测试执行功能的实现
该功能主要是实现不同用例模块中用例的批量执行,与此同时会辅助做一些其他工作:
- 创建测试报告文件,并初始化部分内容:记录测试开始时间、记录各测试模块中用例数量
- 实时输出结果至终端与测试报告文件
- 对输出结果进行排版设计
- 具体代码如下:
test_start(){
t_start=$(date +"%m%d%H%M%S")
report="report_${t_start}" && report_path=./report/${report} && touch ${report_path}
echo "_____________________________________________________________________________" >> ${report_path} && cat ${report_path}
echo "" >> ${report_path} && cat ${report_path}| tail -1
echo " # 测试开始 #" >> ${report_path} && cat ${report_path}| tail -1
echo " # 测试人员A:本轮测试,用例数量:${num_a}条 #" >> ${report_path} && cat ${report_path}| tail -1
echo " # 测试人员B:本轮测试,用例数量:${num_b}条 #" >> ${report_path} && cat ${report_path}| tail -1
echo " # 测试人员C:本轮测试,用例数量:${num_c}条 #" >> ${report_path} && cat ${report_path}| tail -1
echo "_____________________________________________________________________________" >> ${report_path} && cat ${report_path}| tail -1
echo "" >> ${report_path} && cat ${report_path}| tail -1
printf "%-20s %-20s%20s\n" 用例ID 执行结果 用例标题 >> ${report_path} && cat ${report_path}| tail -1
if [ "${num_a}" != "0" ]
then
for i in `seq 1 ${num_a}`
do
test_a${i}
test_result;sleep 1
done
fi
if [ "${num_b}" != "0" ]
then
for i in `seq 1 ${num_b}`
do
test_b${i}
test_result;sleep 1
done
fi
if [ "${num_c}" != "0" ]
then
for i in `seq 1 ${num_c}`
do
test_c${i}
test_result;sleep 1
done
fi
}
测试报告功能的实现
该功能主要实现的是收集测试过程中与测试结束后的数据,并统一输出至文档文件中,并对每一次的测试结果做归档处理,方便后续跟踪某一次的测试结果。
具体实现代码如下:
case_pf(){
if [ "${r}" == "pass" ]
then
let pass+=1
elif [ "${r}" == "fail" ]
then
let fail+=1
fi
let total+=1
}
test_result(){
printf "%-20s %-20s %-20s\n" ${case_id} ${r} ${title} >> ${report_path} && cat ${report_path}| tail -1
}
test_report(){
t_end=$(date +"%m%d%H%M%S")
echo "_____________________________________________________________________________" >> ${report_path} && cat ${report_path}| tail -1
echo "" >> ${report_path} && cat ${report_path}| tail -1
echo "测试开始时间:${t_start}" >> ${report_path}
echo "测试结束时间:${t_end}" >> ${report_path}
echo "测试电脑架构:`uname -m`" >> ${report_path}
echo "执行用例合计:${total}" >> ${report_path}
echo "用例通过数量:${pass}" >> ${report_path}
echo "用例失败数量:${fail}" >> ${report_path}
echo "失败用例ID:${fail_id[*]}" >> ${report_path}
cat ${report_path} | tail -7
echo "_____________________________________________________________________________" >> ${report_path} && cat ${report_path}| tail -1
}
实验验证
为了说明SAT
的工作流程,这里拿一个实际场景举例,本次测试需要自动化执行:测试人员A、测试人员B的用例,无需执行测试人员C的用例:
操作流程如下
- 收集测试人员A、测试人员B最新的测试用例模块文件,放入目录"SAT/case/"下。
- SAT目录下启动终端,运行命令
su
进入Root。
- 因部分命令需要root权限,使用sudo+命令需要提示用户输入密码,不友好。
- 若用户使用普通用户权限运行,则给出对应提示:
请已root用户运行该脚本,点击Enter退出
,并关闭。
- 终端实时查看测试过程,过程中会输出用例数据与用例执行结果。
- 等待测试完成后,终端可查看测试结果,重点关注失败用例ID,对其做二次验证并提交Bug单。
- 关闭终端后若还需查看测试结果,进入"SAT/report/"目录,根据文件命名中时间戳定位测试报告文件并查看。
终端中与测试报告中内容展示一致,主要体现自动化测试流程与结果,可看到下方输入内容,展示各关键信息了:
_____________________________________________________________________________
# 测试开始 #
# 测试人员A:本轮测试,用例数量:5条 #
# 测试人员B:本轮测试,用例数量:1条 #
# 测试人员C:本轮测试,用例数量:0条 #
_____________________________________________________________________________
用例ID 执行结果 用例标题
xxxxxx pass 检查内核信息与版本号
xxxxxx fail 检查内核启动信息
xxxxxx pass 验证perl环境
xxxxxx pass 验证python环境
xxxxxx pass 验证系统预装软件包状态
xxxxxx fail 创建test文件夹
_____________________________________________________________________________
测试开始时间:0818102422
测试结束时间:0818102428
测试电脑架构:x86_64
执行用例合计:6
用例通过数量:4
用例失败数量:2
失败用例ID:xxxxxx xxxxxx
_____________________________________________________________________________
# 测试完毕,测试报告生成在'./report'目录,点击Enter退出! #
小结
如此一个简单的自动化测试框架就完成了,已经可以很好的满足日常测试,以上是初期的一个简单设计。经过后续的迭代,目前已经支持各种功能配置、环境检测、测试流程控制、邮件发送测试报告、自动代码提交、代码格式/规范扫描等。大家可根据自己的项目需要做相应的完善,这里仅提供一个思路。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)