使用Jenkins进行持续集成
目录
- 1、准备执行接口
- 1.1、创建测试套件
- 1.2、获取执行接口
- 2、准备执行脚本
- 2.1、检查集成环境
- 2.2、转换测试用例
- 2.3、创建接口执行项目
- 3、集成到Jenkins上
- 3.1、创建项目
- 3.2、执行项目
由于目前HttpRunnerManager暂时还没有以插件的方式与Jenkins集成,本节讲解是以获取HttpRunnerManager的执行测试套件接口方式来与Jenkins进行集成。讲解的HttpRunnerManager与Jenkins不在同一环境,但都是在Windows环境下。
1、准备执行接口
1.1、创建测试套件
登录HttpRunnerManager,创建测试套件。
如图所示:套件(TestSuite1)添加2条测试用例,套件(TestSuite2)添加3条测试用例。
1.2、获取执行接口
1、打开Fiddler,开启监听。之后登录HttpRunnerManager,选择测试套件(例如TestSuite1),点击运行,选择运行环境,执行方式选择异步,点击确定进行执行。
2、此时Fiddler已经抓取到执行的测试套件接口信息。
URL链接:
请求信息:
响应信息:
HttpRunnerManager报告列表里可查看执行后的测试结果。
3、使用Fiddler导出抓取到的接口,点击File--->Export Sessions--->All Sessions。
选择默认即可,点击Next。
如图所示:导出的接口为.har文件。
同理,HttpRunnerManager执行测试套件(TestSuite2),Fiddler抓取此接口,之后导出的接口也是.har文件。
2、准备执行脚本
2.1、检查集成环境
首先确保Jenkins必须有Python环境。
之后检查Jenkins所在环境是否安装了HttpRunner,如果没有,则需要先安装HttpRunner。
打开命令行输入安装命令pip install httprunner
安装完成后,输入hrun -V查看HttpRunner版本为1.5.15。
之后还要安装har2case(将HAR文件格式转换为HttpRunner的YAML / JSON测试用例)。
打开命令行输入安装命令pip install har2case
安装完成后,输入har2case -V查看har2case版本为0.1.11。
2.2、转换测试用例
转为YAML文件格式命令har2case XXX.har XXX.yml
例如har2case TestDemo1.har TestDemo1.yml
如图所示:HAR格式转换为YAML格式的测试用例。
转为JSON文件格式命令har2case XXX.har XXX.json
例如har2case TestDemo1.har TestDemo1.json
如图所示:HAR格式转换为JSON格式的测试用例。
2.3、创建接口执行项目
1、创建接口执行项目(HttpRunnerManagerForJenkins)。
case目录存放测试用例(本示例以.json为例:TestDemo1.json、TestDemo2.json)
reports目录存放执行后自动生成的测试报告
debugtalk.py用于自定义函数
run.bat为调用的执行脚本(在Windows环境下)
run.sh为调用的执行脚本(在Linux环境下)
2、运行单个测试用例进行调试,命令行跳转到case目录里,输入执行命令hrun XXX.json
如图所示:输入执行命令hrun TestDemo1.json,执行TestDemo1.json,没有报错。
在当前case目录里,自动生成reports目录,并生成执行后的测试报告。
查看生成的测试报告,发现接口的响应信息显示为HttpRunnerManager的登录页面,也就是说此用例接口没有执行成功,卡在了登录页面上。
经过分析后,发现此测试接口是需要Cookie才可以正常发送请求的,且这个Cookie信息不是固定值,需要在debugtalk.py里自定义函数来获取Cookie值(抓取登录接口的Cookie),之后接口用例引用这个变量就可以了。
HttpRunnerManager的登录接口http://10.53.27.229:8000/api/login/,输入用户名与密码,进行登录。
还是使用Fiddler抓取此登录操作,可以看到Cookie信息,之后就可以在debugtalk.py里写个登录接口并返回Cookie值的函数。
3、debugtalk.py文件内容(新增函数:获取cookie(sessionid)、设置时间、hook机制等待):
代码语言:javascript复制#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import time
# 获取cookie(sessionid)
def get_cookie():
url = 'http://10.53.27.229:8000/api/login/'
headers = {
"X-Requested-With": "XMLHttpRequest"
}
data = {
"account": "wangmeng",
"password": "admin123456"
}
res = requests.post(url=url, data=data, headers=headers)
print(res.headers.get('Set-Cookie'))
print(res.headers.get('Set-Cookie').split(';')[0])
cookie = res.headers.get('Set-Cookie').split(';')[0]
return cookie
# 设置时间
def my_time():
s = 20
return s
# hook机制等待
def hook_sleep():
time.sleep(my_time())
4、测试用例(TestDemo1.json)文件内容(添加Cookie,自定义用例名称、测试报告名称,添加断言,添加执行开始与结束hook机制):
代码语言:javascript复制[
{
"config": {
"name": "testset description",
"variables": [],
"request": {
"base_url": "",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"Cookie": "${get_cookie()}"
}
}
}
},
{
"test": {
"name": "TestDemo1",
"request": {
"url": "http://10.53.27.229:8000/api/run_batch_test/",
"method": "POST",
"headers": {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json"
},
"json": {
"id": {
"suite_2": "2"
},
"env_name": "http://127.0.0.1:8083",
"type": "suite",
"report_name": "TestDemo1测试结果"
}
},
"validate": [
{
"eq": [
"status_code",
200
]
},
{
"eq": [
"headers.Content-Type",
"text/html; charset=utf-8"
]
},
{
"contains": [
"content",
"用例执行中"
]
}
],
"setup_hooks": [
"${hook_sleep()}"
],
"teardown_hooks": [
"${hook_sleep()}"
]
}
}
]
5、测试用例(TestDemo2.json)文件内容(添加Cookie,自定义用例名称、测试报告名称,添加断言,添加执行开始与结束hook机制):
代码语言:javascript复制[
{
"config": {
"name": "testset description",
"variables": [],
"request": {
"base_url": "",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"Cookie": "${get_cookie()}"
}
}
}
},
{
"test": {
"name": "TestDemo2",
"request": {
"url": "http://10.53.27.229:8000/api/run_batch_test/",
"method": "POST",
"headers": {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json"
},
"json": {
"id": {
"suite_7": "7"
},
"env_name": "http://127.0.0.1:8083",
"type": "suite",
"report_name": "TestDemo2测试结果"
}
},
"validate": [
{
"eq": [
"status_code",
200
]
},
{
"eq": [
"headers.Content-Type",
"text/html; charset=utf-8"
]
},
{
"contains": [
"content",
"用例执行中"
]
}
],
"setup_hooks": [
"${hook_sleep()}"
],
"teardown_hooks": [
"${hook_sleep()}"
]
}
}
]
6、脚本文件run.bat内容(在Windows环境下使用):
代码语言:javascript复制start cmd /c "cd �%&&hrun case/"
7、脚本文件run.sh内容(在Linux环境下使用):
代码语言:javascript复制#!/bin/bash
set -eu
# 当前路径
my_dir=$(cd "$(dirname ${0})";pwd)
root_dir=$(dirname "${my_dir}")
# 运行测试用例
hrun ./case/
# 清理过期reports
if [[ -d ${my_dir}/reports ]];then
find ${my_dir}/reports/ -maxdepth 1 -type f -mtime 7 -exec rm -rf {} ;
fi
8、再次执行此接口,如果此接口用例引用debugtalk.py文件里的函数,则不能单独直接执行,否则会报错找不到要使用的函数。如图所示:找不到get_cookie函数。
则需要跳转到HttpRunnerManagerForJenkins项目的根目录,此时执行run.bat即可(在Windows环境下,如果在Linux环境下执行run.sh即可)。
执行完成后,在HttpRunnerManagerForJenkins项目的reports目录里生成测试报告。
打开测试报告。
点击详情,可以看到已经登录成功,接口响应信息正确。
之后登录到HttpRunnerManager里,报告列表里可以看到接口执行后新生成的测试报告。
打开测试报告,可以查看每个接口的详细信息。
3、集成到Jenkins上
3.1、创建项目
1、登录Jenkins(在Windows环境下),点击新建任务。
2、输入一个任务名称(例如TestDemo),选择构建一个自由风格的软件项目即可,点击确定。
3、源码管理,可以使用Git或者Svn,这里已经将之前创建的HttpRunnerManagerForJenkins项目代码上传到GitHub上。
选择Git,使用HTTPS。
在Repository URL输入GitHub项目HTTPS地址即可。
4、构建,增加构建步骤(执行Windows批处理命令)。
输入命令run.bat
注:Jenkins如果是在Linux环境,需要增加构建步骤(执行shell)。
5、最后保存即可。
还可以添加定时构建、轮询SCM,发布HTML报告,发送邮件等设置。
3.2、执行项目
1、点击构建按钮,执行项目。
之后左下角出现执行进度状态条。
2、注意:执行完成后,HttpRunnerManager的报告列表里并没有新生成测试报告,且Jenkins的控制台输出提示Process leaked file descriptors.
分析原因为Jenkins默认会在Build结束后Kill掉所有的衍生进程,用官方的话来说就是:
To reliably kill processes spawned by a job during a build, Jenkins contains a bit of native code to list up such processes and kill them.
解决方法:
打开Jenkins--->系统管理--->系统设置,在全局属性里,新增环境变量:
键 BUILD_ID 值 allow_to_run_as_daemon start_my_service
如图所示:之后点击保存即可。
3、再次执行,虽然Jenkins控制台还是提示Process leaked file descriptors.,但衍生进程可以正常执行。如图所示:
之后登录到HttpRunnerManager里,报告列表里可以看到Jenkins执行项目完成后新生成的测试报告。