欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

SHELL自动化--接口测试

程序员文章站 2023-11-19 16:01:46
#!/bin/bash fileNum=`ls /bin/testShell/apiCheck_shell/logs/ | grep $(date "+%Y-%m-%d") | wc -w`day=$(date "+%Y-%m-%d")-${fileNum}# 设置并发的进程数thread_num= ......

#!/bin/bash

filenum=`ls /bin/testshell/apicheck_shell/logs/ | grep $(date "+%y-%m-%d") | wc -w`
day=$(date "+%y-%m-%d")-${filenum}
# 设置并发的进程数
thread_num=`cat /bin/testshell/apicheck_shell/check.conf | grep thread_num`
thread_num=${thread_num#*thread_num=}
apinum=0
annotationnum=0
passnum=0
failnum=0
faillist="\n"
echo "" > /bin/testshell/apicheck_shell/logs/apicheck_err.log
echo "" > /bin/testshell/apicheck_shell/logs/result.log

tmpfifo=/tmp/$$.fifo #声明管道名称,'$$'表示脚本当前运行的进程pid
mkfifo $tmpfifo #创建管道
exec 6<>${tmpfifo} #创建文件标示符“6”,这个数字可以为除“0”、“1”、“2”之外的所有未声明过的字符,以读写模式操作管道文件;系统调用exec是以新的进程去代替原来的进程,但进程的pid保持不变,换句话说就是在调用进程内部执行一个可执行文件
rm -rf ${tmpfifo} #清除创建的管道文件

# 为文件描述符创建占位信息
for ((i=1;i<=${thread_num};i++))
do
{
#借用read命令一次读取一行的特性,使用一个echo默认输出一个换行符,来确保每一行只有一个线程占位;这里让人联想到生产者&消费者模型,管道文件充当消息队列,来记录消费者的需求,然后由生产者去领任务,并完成任务,这里运用了异步解耦的思想
echo
}
done >&6 # 事实上就是在fd6中放置了$thread_num个回车符

#发送请求并记录请求返回值
send()
{
echo "$(date "+%y-%m-%d %h:%m:%s"):============================================================================================================================" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
max_time=`cat /bin/testshell/apicheck_shell/project/${project}/server.conf | grep max_time:`
max_time=${max_time#*max_time:}
contenttype=`cat /bin/testshell/apicheck_shell/project/${project}/server.conf | grep contenttype:`
contenttype=${contenttype#*contenttype:}
if [[ "${project}" == "test-1" ]] || [[ "${project}" == "test-2" ]]
then
echo "$(date "+%y-%m-%d %h:%m:%s"): curl --connect-timeout ${max_time} -m ${max_time} -s -i -x post --cookie \"${cookies}\" -h \"content-type\":\"${contenttype}\" -d \"${para}\" ${url}" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
result=$(curl --connect-timeout ${max_time} -m ${max_time} -s -i -x post --cookie "${cookies}" -h "content-type":"${contenttype}" -d "${para}" ${url})
elif [[ "${url}" =~ "?" ]]
then
echo "$(date "+%y-%m-%d %h:%m:%s"): curl --connect-timeout ${max_time} -m ${max_time} -s -i -x get -h \"content-type\":\"${contenttype}\" ${url}${para}" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
result=$(curl --connect-timeout ${max_time} -m ${max_time} -s -i -x get -h "content-type":"${contenttype}" ${url}${para})
else
echo "$(date "+%y-%m-%d %h:%m:%s"): curl --connect-timeout ${max_time} -m ${max_time} -s -i -x post -h \"content-type\":\"${contenttype}\" -d \"${para}\" ${url}" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
result=$(curl --connect-timeout ${max_time} -m ${max_time} -s -i -x post -h "content-type":"${contenttype}" -d "${para}" ${url})
fi
result="{${result#*\{}"
result="${result%\}*}}"
echo "$(date "+%y-%m-%d %h:%m:%s"):【result】${result}" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
}

# 参数处理 获取para,并替换里面的省、市、区、街道、地址,如果需要进行urlencode,则进行url编码
paraseting()
{
para=${line%|*}
para=${para#*|}
#citycode=${line2%%,*}
#adcode=$(grep "${citycode}" /bin/testshell/apicheck_shell/codes.csv)
#adcode=${adcode##*,}
#line2=${line2#*,}
#province=${line2%%,*}
#line2=${line2#*,}
#cityname=${line2%%,*}
#line2=${line2#*,}
#area=${line2%,*}
#line2=${line2#*,}
#street=${line2}
#address=${province}${cityname}${area}${street}
if [[ ${para} =~ "urlencode-gb2312-" ]]
then
address=${para#*urlencode-gb2312-}
address=${address%&*}
urlencodeaddress=$(java -jar /bin/testshell/apicheck_shell/urlencode-1.0.0.jar ${address} gb2312)
para=${para//"urlencode-gb2312-"/""}
para=${para//"${address}"/"${urlencodeaddress}"}
fi
#para=${para//address/${address}}
#para=${para//citycode/${citycode}}
#para=${para//adcode/${adcode}}
#para=${para//province/${province}}
#para=${para//cityname/${cityname}}
#para=${para//area/${area}}
}

# 获取check.conf中配置为on的项目数
getprojectnum()
{
projectlist=$(grep "on=" /bin/testshell/apicheck_shell/check.conf)
projectlist=${projectlist#*on=}
}

#遍历api.conf中的所有接口记录
traverseapi()
{
while read line
do
let apinum++
name="${line%%】*}】"
url=${line#*】}
url=${url%%|*}
returnlist=${line##*|}
cookies=`cat /bin/testshell/apicheck_shell/project/${project}/server.conf | grep cookies:`
cookies=${cookies#*cookies:}
if [ "${line:0:1}" == "#" ]
then
let annotationnum++
echo "$(date "+%y-%m-%d %h:%m:%s"):当前行${name}被注释,不进行校验" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
continue
fi
# 调用参数处理函数
paraseting
# 调用函数,发送相关请求,并记录返回结果
send
# 调用函数,校验返回结果
checkresult
done < /bin/testshell/apicheck_shell/project/${project}/api.conf
}

# 根据断言关键字,校验返回结果
checkresult()
{
temp_pass_return=""
temp_fail_return=""
temp_pass_result=""
temp_fail_result=""
temp_key=""
temp_value=""
value=""
if [ "${returnlist}" != "" ]
then
# 根据switch中的配置,获取断言方式:精确匹配、包含
isexact=`cat /bin/testshell/apicheck_shell/project/${project}/switch.conf | grep isexact=`
isexact=${isexact#*isexact=}
for return in $returnlist
do
return=${return//"\\"/"\\\\\\"} # 针对期望值中有反斜杠的情况作特殊处理
if [ "$isexact" == "no" ] # 断言方式为:包含
then
# 如果返回的结果中包含断言关键字return,则获取断言关键字return对应的value
if [[ $result =~ $return ]]
then
value=${result#*${return}\":\"}
value=${value%%\"*}
# 根据switch中的配置,判断是否要作去空格处理
istrim=`cat /bin/testshell/apicheck_shell/project/${project}/switch.conf | grep istrim=`
istrim=${istrim#*istrim=}
if [ "${istrim}" == "yes" ]
then
value=${value// /}
fi
fi
if [ "${value}" != "" ]
then
temp_pass_return="${temp_pass_return} ${return}"
temp_pass_result="${temp_pass_result} \"${return}\":\"${value}\""
else
temp_fail_return="${temp_fail_return} ${return}"
temp_fail_result="${temp_fail_result} \"${return}\":\"${value}\""
fi
else # 断言方式为:精确匹配
if [[ $result =~ $return ]]
then
return=${return//"\\\\"/"\\"}
temp_pass_return="${temp_pass_return} ${return}"
temp_key="${return%:*}"
temp_value="${result#*${temp_key}:}"
temp_value="${temp_value%%,*}"
temp_key=${temp_key//"\\\\"/"\\"}
temp_pass_result="${temp_pass_result} ${temp_key}:${temp_value}"
else
return=${return//"\\\\"/"\\"}
temp_fail_return="${temp_fail_return} ${return}"
temp_key="${return%:*}"
temp_value="${result#*${temp_key}:}"
temp_value="${temp_value%%,*}"
temp_key=${temp_key//"\\\\"/"\\"}
temp_fail_result="${temp_fail_result} ${temp_key}:${temp_value}"
fi
fi
done
# 如果temp_fail_return长度大于0,则表示有校验失效
if [ ${#temp_fail_return} -gt 0 ]
then
let failnum++
echo "$(date "+%y-%m-%d %h:%m:%s"): ${name}${url}【返回异常!】" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
echo "$(date "+%y-%m-%d %h:%m:%s"):============================================================================================================================" >> /bin/testshell/apicheck_shell/logs/apicheck_err.log
echo "$(date "+%y-%m-%d %h:%m:%s"): 【para】${para}" >> /bin/testshell/apicheck_shell/logs/apicheck_err.log
echo "$(date "+%y-%m-%d %h:%m:%s"): 【result】${result}" >> /bin/testshell/apicheck_shell/logs/apicheck_err.log
echo "$(date "+%y-%m-%d %h:%m:%s"): ${name}${url}【返回异常!】" >> /bin/testshell/apicheck_shell/logs/apicheck_err.log
echo -e "$(date "+%y-%m-%d %h:%m:%s"): ${name}${url}\033[41;37m 【返回异常!】 \033[0m"
faillist="${faillist}${name}${url}【返回异常!】\n"
else
let passnum++
echo "$(date "+%y-%m-%d %h:%m:%s"): ${name}${url}【可正常访问】" >> /bin/testshell/apicheck_shell/logs/apicheck${day}.log
echo -e "$(date "+%y-%m-%d %h:%m:%s"): ${name}${url}\033[42;37m 【可正常访问】 \033[0m"
fi
echo "$(date "+%y-%m-%d %h:%m:%s"): 【para】${para}"
echo -e "$(date "+%y-%m-%d %h:%m:%s"): 【预期结果】\033[42;37m${temp_pass_return}\033[0m \033[41;37m${temp_fail_return}\033[0m"
for temp_pass in ${temp_pass_result}
do
result=${result//"${temp_pass}"/"\033[42;37m${temp_pass}\033[0m"}
done
for temp_fail in ${temp_fail_result}
do
result=${result//"${temp_fail}"/"\033[41;37m${temp_fail}\033[0m"}
done
echo -e "$(date "+%y-%m-%d %h:%m:%s"): 【返回结果】${result}"
fi
}

# 调用函数,获取项目数
getprojectnum
#从文件描述符管道中,获取一个管道的线程占位然后开始执行操作;read中 -u 后面跟fd,表示从文件描述符中读入,该文件描述符可以是exec新开启的
read -u6
{
# 遍历所有状态为on的project
for project in $projectlist
do
# 调用函数,遍历所有项目
traverseapi
echo "" >&6
#任务执行完后在fd6中写入一个占位符,以保证这个线程执行完后,线程继续保持占位,继而维持管道中永远是thread_num个线程数,&表示该部分命令/任务放入后台不占当前的bash,实现并行处理
done
echo "$(date "+%y-%m-%d %h:%m:%s"): 此次共检测接口【${apinum}】个" >> /bin/testshell/apicheck_shell/logs/result.log
echo "$(date "+%y-%m-%d %h:%m:%s"): 注释【${annotationnum}】个" >> /bin/testshell/apicheck_shell/logs/result.log
echo "$(date "+%y-%m-%d %h:%m:%s"): 成功【${passnum}】个" >> /bin/testshell/apicheck_shell/logs/result.log
echo "$(date "+%y-%m-%d %h:%m:%s"): 失败【${failnum}】个" >> /bin/testshell/apicheck_shell/logs/result.log
echo -e "$(date "+%y-%m-%d %h:%m:%s"): 失败记录列表如下:${faillist}" >> /bin/testshell/apicheck_shell/logs/result.log
} &
wait # 等待父进程的子进程都执行结束后再结束父进程
exec 6>&- # 关闭fd6管道