接口自动化测试平台FasterRunner系列(一)
简介、安装部署、启动服务、访问地址、配置补充
目录
- 1、简介
- 2、安装部署
- 2.1、部署后端FasterRunner
- 2.2、部署前端FasterWeb
- 3、启动服务
- 3.1、启动后端FasterRunner
- 3.2、启动前端FasterWeb
- 4、访问地址
- 4.1、注册地址
- 4.2、登录地址
- 5、配置补充
- 5.1、定时任务
- 5.2、发送邮件
- 5.3、启动关闭
- 5.3.1、启动服务
- 5.3.2、关闭服务
1、简介
FasterRunner是在原接口自动化测试平台HttpRunnerManager基础上进行了全新的升级,页面样式全新改版,平台架构进行了前后端(Vue Django)分离设计。整体操作方式跟HttpRunnerManager基本相同,关于HttpRunnerManager的部署与使用等,可点击HttpRunnerManager系列章节进行查阅。
官方网址:
后端:https://github.com/httprunner/FasterRunner
前端:https://github.com/httprunner/FasterWeb
2、安装部署
本篇讲解是在Linux环境下进行安装部署(Windows环境安装方法类似)。
使用Python版本为3.6.10
将前后端包下载后并解压到自定义目录里
2.1、部署后端FasterRunner
1、安装依赖库,FasterRunner根目录下执行pip3 install -r requirements.txt
2、安装并配置MySQL,连接数据库, 新建一个DB,例如fastrunner
3、修改FasterRunner/FasterRunner/settings.py文件,修改DATABASES字典相关配置
DATABASES(数据库信息以实际部署为准):
4、安装Erlang(RabbitMQ环境需要先有Erlang开发环境)
5、安装并启动RabbitMQ
6、修改FasterRunner/FasterRunner/settings.py文件,修改BROKER_URL(配置RabbitMQ的IP、Username、Password)
7、切换到FasterRunner根目录,Linux环境执行dos2unix ./start.sh
8、FasterRunner根目录下创建文件夹logs,位置FasterRunner/logs
9、生成数据迁移脚本,根目录下执行:
python3 manage.py makemigrations fastrunner fastuser
10、应用到DB生成数据表,根目录下执行:
python3 manage.py migrate fastrunner
python3 manage.py migrate fastuser
python3 manage.py migrate djcelery
2.2、部署前端FasterWeb
1、安装Node.js
本篇所搭建的版本为:node版本12.18.3,npm版本6.14.6
2、进入FasterWeb根目录下,安装依赖项,执行命令npm install
3、修改根目录下default.conf配置文件,server_name的IP(宿主机IP),端口默认8080
如图所示:修改端口为8085
4、修改FasterWeb/config/index.js文件,端口port
如图所示:修改端口为8085
5、修改FasterWeb根目录下的package.json文件
修改为"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0",
6、修改FasterWeb/src/restful/api.js文件,baseUrl地址,即为FasterRunner容器运行的宿主机地址
如图所示:FasterRunner宿主机端口为8086
3、启动服务
3.1、启动后端FasterRunner
在FasterRunner根目录下依次执行:
代码语言:javascript复制nohup python3 manage.py runserver 0.0.0.0:8086 &
nohup python3 manage.py celery -A FasterRunner worker -l info --logfile=/root/MyTest/FasterRunner/logs/worker.log 2>&1 &
nohup python3 manage.py celery beat -l info >> /root/MyTest/FasterRunner/logs/beat.log 2>&1 &
注:如果是Windows环境下,可在当前根目录下创建.bat批量执行启动服务文件
文件内容:
代码语言:javascript复制start cmd /c "cd �%&&del /a celerybeat.pid"
start cmd /k "cd �%&&TIMEOUT /T 2&&python manage.py runserver 0.0.0.0:8086"
start cmd /k "cd �%&&TIMEOUT /T 4&&python manage.py celery -A FasterRunner worker -l info"
start cmd /k "cd �%&&TIMEOUT /T 6&&python manage.py celery beat -l info"
3.2、启动前端FasterWeb
在FasterWeb根目录下执行:
1、开发模式启动Node,默认端口是8080
代码语言:javascript复制npm run dev
或者输入,后台启动,并写入日志
代码语言:javascript复制nohup npm start >> ~/node.log 2>&1 &
注:如果是Windows环境下,可在当前根目录下创建.bat批量执行启动服务文件
文件内容:
代码语言:javascript复制start cmd /k "cd �%&&npm run dev"
如何杀指定的程序进程?
代码语言:javascript复制查进程号:netstat -nap|grep 端口号
杀进程:kill -9 进程号
2、扩展:可安装部署pm2
(1)安装pm2
代码语言:javascript复制npm install -g pm2
(2)配置pm2,创建软链接
代码语言:javascript复制ln -s ~/root/node-v12.18.3-linux-x64/bin/pm2 /usr/sbin/pm2
(3)在FasterWeb根目录下,pm2启动Node服务
代码语言:javascript复制pm2 start npm --watch --name fasterweb -- run start
(4)查看pm2运行服务的状态
代码语言:javascript复制pm2 list
如图所示:FasterWeb服务已启动。
pm2命令:
代码语言:javascript复制列出所有进程/应用 pm2 list
重新启动所有进程/应用 pm2 restart all
根据应用id停止指定应用 pm2 stop [ID]
4、访问地址
4.1、注册地址
http://IP:端口/fastrunner/register
例如http://localhost:8085/fastrunner/register
如图所示:注册页面已自定义修改
4.2、登录地址
http://IP:端口/fastrunner/login
例如http://localhost:8085/fastrunner/login
如图所示:登录页面已自定义修改
5、配置补充
因原项目框架里没有配置定时任务和发送邮件等功能,这里需要对框架进行配置与补充。
5.1、定时任务
此功能的作用就是按设置指定的时间来执行测试用例集。
1、修改FasterRunner/FasterRunner/settings.py文件
脚本内容:
代码语言:javascript复制djcelery.setup_loader()
CELERY_ENABLE_UTC = True
CELERY_TIMEZONE = 'Asia/Shanghai'
BROKER_URL = 'amqp://guest:guest@127.0.0.1:5672//'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_RESULT_EXPIRES = 7200
CELERYD_CONCURRENCY = 10 if DEBUG else 10
CELERYD_MAX_TASKS_PER_CHILD = 200
2、启动定时服务(启动服务子章节里已经启动)
代码语言:javascript复制nohup python3 manage.py celery -A FasterRunner worker -l info --logfile=/root/MyTest/FasterRunner/logs/worker.log 2>&1 &
nohup python3 manage.py celery beat -l info >> /root/MyTest/FasterRunner/logs/beat.log 2>&1 &
3、修改脚本
(1)修改FasterRunner/fastrunner/utils/task.py文件
脚本内容:
代码语言:javascript复制self.__email = {
"strategy": kwargs["strategy"],
"copy": kwargs["copy"],
"receiver": kwargs["receiver"],
"corntab": self.__corntab,
"project": self.__project,
"name": kwargs["name"]
}
(2)修改FasterRunner/fastrunner/tasks.py文件
脚本内容:
代码语言:javascript复制project = kwargs["project"]
receiver = kwargs["receiver"]
Cc = kwargs["copy"]
title = kwargs["name"]
5.2、发送邮件
配置定时任务时,可设置发送邮件功能。
1、修改FasterRunner/FasterRunner/settings.py文件
脚本内容:
代码语言:javascript复制# 发邮件
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_SEND_USERNAME = 'wangmcn@163.com' # 定时任务报告发送邮箱,支持163,qq,sina,企业qq邮箱等,注意需要开通smtp服务
EMAIL_SEND_PASSWORD = 'XXXXXXXX' # 邮箱密码
EMAIL_PORT = 25
EMAIL_USE_TLS = True
2、在FasterRunner/fastrunner/utils目录下,创建emails.py文件
脚本内容:
代码语言:javascript复制import smtplib
from email.mime.text import MIMEText
from email.header import Header
from FasterRunner.settings import EMAIL_SEND_USERNAME, EMAIL_SEND_PASSWORD
def send_email_reports(receiver,save_summary,Cc=None,title=None):
receiver = receiver.rstrip(';')
all_receivers = receiver.split(';')
if '@sina.com' in EMAIL_SEND_USERNAME:
smtpserver = 'smtp.sina.com'
elif '@163.com' in EMAIL_SEND_USERNAME:
smtpserver = 'smtp.163.com'
else:
smtpserver = 'smtp.exmail.qq.com'
if title:
subject = "【%s】接口自动化测试报告"%title
else:
subject = "接口自动化测试报告"
smtp = smtplib.SMTP_SSL(smtpserver, 465)
smtp.login(EMAIL_SEND_USERNAME, EMAIL_SEND_PASSWORD)
msg = MIMEText(save_summary, "html", "utf-8")
msg["Subject"] = Header(subject, "utf-8")
msg['From'] = Header('测试报告人', 'utf-8')
msg['To'] = receiver
# 处理抄送
if Cc:
Cc = Cc.rstrip(';')
msg['Cc'] = Cc
all_receivers = receiver ';' Cc
all_receivers = all_receivers.split(';')
smtp.sendmail(EMAIL_SEND_USERNAME, all_receivers, msg.as_string())
3、修改FasterRunner/fastrunner/tasks.py文件
修改后的脚本内容:
代码语言:javascript复制from celery import shared_task
from django.core.exceptions import ObjectDoesNotExist
from fastrunner import models
from fastrunner.utils.loader import save_summary, debug_suite, debug_api
from fastrunner.utils.emails import send_email_reports
import time
@shared_task
def async_debug_api(api, project, name, config=None):
"""异步执行api
"""
summary = debug_api(api, project, config=config, save=False)
save_summary(name, summary, project)
@shared_task
def async_debug_suite(suite, project, obj, report, config):
"""异步执行suite
"""
summary = debug_suite(suite, project, obj, config=config, save=False)
save_summary(report, summary, project)
@shared_task
def schedule_debug_suite(*args, **kwargs):
"""定时任务
"""
print("定时任务start.....")
project = kwargs["project"]
receiver = kwargs["receiver"]
Cc = kwargs["copy"]
title = kwargs["name"]
print("receiver****:%s"%receiver)
print("args****:" str(args))
print("kwargs****:%s"%kwargs)
print("定时任务end.....")
receiver = receiver.strip()
Cc = Cc.strip()
suite = []
test_sets = []
config_list = []
for pk in args:
try:
name = models.Case.objects.get(id=pk).name
suite.append({
"name": name,
"id": pk
})
except ObjectDoesNotExist:
pass
for content in suite:
test_list = models.CaseStep.objects.
filter(case__id=content["id"]).order_by("step").values("body")
testcase_list = []
config = None
for content in test_list:
body = eval(content["body"])
if "base_url" in body["request"].keys():
config = eval(models.Config.objects.get(name=body["name"], project__id=project).body)
continue
testcase_list.append(body)
config_list.append(config)
test_sets.append(testcase_list)
summary = debug_suite(test_sets, project, suite, config_list, save=False)
save_summary("", summary, project, type=3)
# 整理数据
testTime = summary['time']['start_at']
testTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(testTime))
durTime = str(summary['time']['duration'])[:8]
totalApi = summary['stat']['testsRun']
successApi = summary['stat']['successes']
FailApi = summary['stat']['failures']
errorApi = summary['stat']['errors']
skipApi = summary['stat']['skipped']
htmll = """
<table border="1" cellpadding="0" cellspacing="0" width="700px">
<tr style="background-color: #f8f8fa">
<th>测试时间</th>
<th>持续时间</th>
<th>Total</th>
<th>Success</th>
<th>Failed</th>
<th>Error</th>
<th>Skipped</th>
</tr>
<tr>
<td>%s</td>
<td>%s 秒</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>
</table>
<div style="height: 30px"></div>
<table border="1" cellpadding="0" cellspacing="0" width="700px">
<tr style="background-color: #f8f8fa">
<th>名称</th>
<th>请求地址</th>
<th>请求方法</th>
<th>响应时间(ms)</th>
<th>测试结果</th>
</tr>
""" % (
testTime, durTime, totalApi, successApi, FailApi, errorApi, skipApi
)
# 名称/请求地址/请求方法/响应时间/测试结果
for i in summary['details']: # [{},{}]
detail = i['records'] # 列表
for d in detail:
name = d['name']
uurl = d['meta_data']['request']['url']
method = d['meta_data']['request']['method']
responseTime = d['meta_data']['response']['response_time_ms']
iresult = d['status']
htmll = """
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s (ms)</td>
<td>%s</td>
</tr>
""" % (name, uurl, method, responseTime, iresult)
htmll = htmll '</table>'
if Cc:
send_email_reports(receiver, htmll, Cc=Cc,title=title)
else:
send_email_reports(receiver, htmll,title=title)
5.3、启动关闭
5.3.1、启动服务
创建start.sh启动文件
文件内容:
代码语言:javascript复制#!/bin/bash
# 启动 FasterWeb
echo -e "启动 FasterWeb"
cd /root/MyTest/FasterWeb/
nohup npm start >> ~/node.log 2>&1 &
# 启动 FasterRunner
echo -e "启动 FasterRunner"
cd /root/MyTest/FasterRunner/
nohup python3 manage.py runserver 0.0.0.0:8086 >> /root/MyTest/FasterRunner/logs/django.log 2>&1 &
# 使用默认的celery.py启动
echo -e "启动 celery beat"
cd /root/MyTest/FasterRunner/
nohnohup python3 manage.py celery beat -l info >> /root/MyTest/FasterRunner/logs/beat.log 2>&1 &
# 使用默认的celery.py启动
echo -e "启动 celery work"
cd /root/MyTest/FasterRunner/
nohup python3 manage.py celery -A FasterRunner worker -l info --logfile=/root/MyTest/FasterRunner/logs/worker.log 2>&1 &
5.3.2、关闭服务
创建stop.sh关闭文件
文件内容:
代码语言:javascript复制#!/bin/bash
# kill django pid
echo -e "shutting down django pid"
pids=$(ps aux | grep "python" | grep "runserver" | awk '{print $2}')
for pid in $pids
do
kill -9 $pid
done
# kill celery beat pid
echo -e "shutting down celery beat pid"
pids=$(ps aux | grep "celery" | grep "FasterRunner" | awk '{print $2}')
for pid in $pids
do
kill -9 $pid
done