- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章基于Python的接口测试框架实例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
背景 。
最近公司在做消息推送,那么自然就会产生很多接口,测试的过程中需要调用接口,我就突然觉得是不是可以自己写一个测试框架?
说干就干,由于现有的接口测试工具Jmeter、SoupUI等学习周期有点长,干脆自己写一个吧,不求人,所有功能自己都能一清二楚.
当然,写工具造轮子只是学习的一种方式,现成成熟的工具肯定比我们自己的写的好用.
开发环境 。
------------------------------------------------------------- 。
操作系统:Mac OS X EI Caption 。
Python版本:2.7 。
IDE:Pycharm 。
------------------------------------------------------------- 。
分析 。
接口是基于HTTP协议的,那么说白了,就是发起HTTP请求就行了,对于Python来说简直就是小菜一碟。直接使用requests就可以很轻松的完成任务.
架构 。
整个框架是比较小的,涉及的东西也比较少,只要分清楚几个模块的功能就行了.
上面是一个接口测试的完整流程。只要一步一步的走下来就行了,并不是很难.
数据源 。
数据源我使用的是JSON来保存,当然,比较广泛的是使用Excel来保存,用JSON来保存是因为JSON用起来比较方便,懒得去读取Excel了,Python对JSON的支持是非常友好的。当然这个就看个人喜好了.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
{
"TestId"
:
"testcase004"
,
"Method"
:
"post"
,
"Title"
:
"单独推送消息"
,
"Desc"
:
"单独推送消息"
,
"Url"
:
"http://xxx.xxx.xxx.xx"
,
"InputArg"
: {
"action"
:
"44803"
,
"account"
:
"1865998xxxx"
,
"uniqueid"
:
"00D7C889-06A0-426E-BAB1-5741A1192038"
,
"title"
:
"测试测试"
,
"summary"
:
"豆豆豆"
,
"message"
:
"12345"
,
"msgtype"
:
"25"
,
"menuid"
:
"203"
},
"Result"
: {
"errorno"
:
"0"
}
}
|
示例如上面代码所示,可以根据个人的业务需要进行调整.
发送请求 。
发送请求就很简单了,用requests模块,然后从JSON中读取发送的参数,post、get或者其他。由于要生成测试报告,那么发送的数据需要做一下记录,我选择用txt文本来作为记录的容器.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
f
=
file
(
"case.json"
)
testData
=
json.load(f)
f.close()
def
sendData(testData, num):
payload
=
{}
# 从json中获取发送参数
for
x
in
testData[num][
'InputArg'
].items():
payload[x[
0
]]
=
x[
1
]
with
open
(
'leftside.txt'
,
'a+'
) as f:
f.write(testData[num][
'TestId'
])
f.write(
'-'
)
f.write(testData[num][
'Title'
])
f.write(
'\n'
)
# 发送请求
data
=
requests.get(testData[num][
'Url'
], params
=
payload)
r
=
data.json()
|
接受返回 。
由于我们是需要生成测试报告的,那么返回的数据我们先需要进行一次存储,可以选择用数据库存储,但是我觉得数据库存储太麻烦了,只要用txt文本作为存储容器即可.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
with
open
(
'rightside.txt'
,
'a+'
) as rs:
rs.write(
'发送数据'
)
rs.write(
'|'
)
rs.write(
'标题:'
+
testData[num][
'Title'
])
rs.write(
'|'
)
rs.write(
'发送方式:'
+
testData[num][
'Method'
])
rs.write(
'|'
)
rs.write(
'案例描述:'
+
testData[num][
'Desc'
])
rs.write(
'|'
)
rs.write(
'发送地址:'
+
testData[num][
'Url'
])
rs.write(
'|'
)
rs.write(
'发送参数:'
+
str
(payload).decode(
"unicode-escape"
).encode(
"utf-8"
).replace(
"u\'"
,
"\'"
))
rs.write(
'|'
)
rs.write(testData[num][
'TestId'
])
rs.write(
'\n'
)
|
结果判定 。
结果判定我使用的是全等于判定。因为我们的接口只需要这样处理就行了,如果有需要,可以写成正则判定.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
with
open
(
'result.txt'
,
'a+'
) as rst:
rst.write(
'返回数据'
)
rst.write(
'|'
)
for
x, y
in
r.items():
rst.write(
' : '
.join([x, y]))
rst.write(
'|'
)
# 写测试结果
try
:
if
cmp
(r, testData[num][
'Result'
])
=
=
0
:
rst.write(
'pass'
)
else
:
rst.write(
'fail'
)
except
Exception:
rst.write(
'no except result'
)
rst.write(
'\n'
)
|
我这里结果有3种,成功、失败或者没结果。结果的设置就看自己的定义了.
生成测试报告 。
测试报告是一个重头戏,由于我发送数据、返回数据和结果都是用txt文本存储,那么每次使用a+模式新增,会让结果越来越多,而且检查起来非常蛋疼.
我的处理方式是每次测试完毕之后,用Python读取txt文本中的数据,然后使用Django动态生成一个结果,然后再使用requests抓取这个网页,保存在Report文件夹中.
网页报告 。
Django的方法我就不多说了,博客中已经有一整个系列文章了。我们需要在views文件中打开之前记录的3个txt文件,然后做一些数据处理,返回给前端,前端用Bootstrap来渲染,就能生成一个比较漂亮的测试报告.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
def
index(request):
rightside
=
[]
result
=
[]
rst_data
=
[]
leftside
=
[]
passed
=
0
fail
=
0
noresult
=
0
with
open
(os.getcwd()
+
'/PortTest/leftside.txt'
) as ls:
for
x
in
ls.readlines():
lf_data
=
{
'code'
: x.strip().split(
'-'
)[
0
],
'title'
: x.strip().split(
'-'
)[
1
]
}
leftside.append(lf_data)
with
open
(os.getcwd()
+
'/PortTest/rightside.txt'
) as rs:
for
x
in
rs.readlines():
row
=
x.strip().split(
'|'
)
rs_data
=
{
"fssj"
: row[
0
],
"csbt"
: row[
1
],
"fsfs"
: row[
2
],
"alms"
: row[
3
],
"fsdz"
: row[
4
],
"fscs"
: row[
5
],
'testid'
: row[
6
]
}
rightside.append(rs_data)
with
open
(os.getcwd()
+
'/PortTest/result.txt'
) as rst:
for
x
in
rst.readlines():
row
=
x.strip().split(
'|'
)
if
row[
len
(row)
-
1
]
=
=
'fail'
:
fail
+
=
1
elif
row[
len
(row)
-
1
]
=
=
'pass'
:
passed
+
=
1
elif
row[
len
(row)
-
1
]
=
=
'no except result'
:
noresult
+
=
1
rs_data
=
[]
for
y
in
row:
rs_data.append(y)
result.append(rs_data)
for
a, b
in
zip
(rightside, result):
data
=
{
"sendData"
: a,
"dealData"
: b,
"result"
: b[
len
(b)
-
1
]
}
rst_data.append(data)
return
render(request,
'PortTest/index.html'
, {
"leftside"
: leftside,
"rst_data"
: rst_data,
"pass"
: passed,
"fail"
: fail,
"noresult"
: noresult})
|
基本上都是一些很基础的知识,字符串分割等等。这里的数据处理为了方便,在获取数据存储的时候就要按照一定的格式来存储,views的方法就很容易做处理.
前端代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
<!DOCTYPE html>
<html lang
=
"en"
>
<head>
<meta charset
=
"UTF-8"
>
<title>Title<
/
title>
<link href
=
"http://zyiz.net/bootstrap/3.0.3/css/bootstrap.min.css"
rel
=
"stylesheet"
>
<script src
=
"http://zyiz.net/jquery/2.0.0/jquery.min.js"
><
/
script>
<script src
=
"http://zyiz.net/bootstrap/3.0.3/js/bootstrap.min.js"
><
/
script>
<
/
head>
<body>
<div
class
=
"container"
>
<div
class
=
"row"
>
<div
class
=
"page-header"
>
<h1>接口测试报告
<small>Design By Sven<
/
small>
<
/
h1>
<
/
div>
<
/
div>
<div
class
=
"row"
>
<div
class
=
"col-md-4"
>
<h3>测试通过 <span
class
=
"label label-success"
>{{
pass
}}<
/
span><
/
h3>
<
/
div>
<div
class
=
"col-md-4"
>
<h3>测试失败 <span
class
=
"label label-danger"
>{{ fail }}<
/
span><
/
h3>
<
/
div>
<div
class
=
"col-md-4"
>
<h3>无结果 <span
class
=
"label label-warning"
>{{ noresult }}<
/
span><
/
h3>
<
/
div>
<
/
div>
<p><
/
p>
<div
class
=
"row"
>
<div
class
=
"col-md-3"
>
<ul
class
=
"list-group"
>
{
%
for
ls
in
leftside
%
}
<li
class
=
"list-group-item"
><a href
=
"#{{ ls.code }}"
>{{ ls.code }}
-
{{ ls.title }}<
/
a><
/
li>
{
%
endfor
%
}
<
/
ul>
<
/
div>
<div
class
=
"col-md-9"
>
{{ x.result }}
{
%
for
x
in
rst_data
%
}
<div
class
=
"panel-group"
id
=
"accordion"
>
{
%
if
x.result
=
=
'pass'
%
}
<div
class
=
"panel panel-success"
>
{
%
elif
x.result
=
=
'fail'
%
}
<div
class
=
"panel panel-danger"
>
{
%
elif
x.result
=
=
'no except result'
%
}
<div
class
=
"panel panel-warning"
>
{
%
endif
%
}
<div
class
=
"panel-heading"
>
<h4
class
=
"panel-title"
>
<a data
-
toggle
=
"collapse"
href
=
"#{{ x.sendData.testid }}"
>
{{ x.sendData.testid }}
-
{{ x.sendData.csbt }}
<
/
a>
<
/
h4>
<
/
div>
<div
id
=
"{{ x.sendData.testid }}"
class
=
"panel-collapse collapse"
>
<div
class
=
"panel-body"
>
<b>{{ x.sendData.fssj }}<
/
b><br>
{{ x.sendData.csbt }}<br>
{{ x.sendData.fsfs }}<br>
{{ x.sendData.alms }}<br>
{{ x.sendData.fsdz }}<br>
{{ x.sendData.fscs }}
<hr>
{
%
for
v
in
x.dealData
%
}
{{ v }}<br>
{
%
endfor
%
}
<
/
div>
<
/
div>
<
/
div>
<
/
div>
<p><
/
p>
{
%
endfor
%
}
<
/
div>
<
/
div>
<
/
div>
<script>
$(function () {
$(window).scroll(function () {
if
($(this).scrollTop() !
=
0
) {
$(
"#toTop"
).fadeIn();
}
else
{
$(
"#toTop"
).fadeOut();
}
});
$(
"body"
).append(
"<div id=\"toTop\" style=\"border:1px solid #444;background:#333;color:#fff;text-align:center;padding:10px 13px 7px 13px;position:fixed;bottom:10px;right:10px;cursor:pointer;display:none;font-family:verdana;font-size:22px;\">^</div>"
);
$(
"#toTop"
).click(function () {
$(
"body,html"
).animate({scrollTop:
0
},
800
);
});
});
<
/
script>
<
/
body>
<
/
html>
|
测试报告效果图 。
最后 。
用Python写一个工具很容易,主要还是要能更方便地满足实际工作中的使用需要为目的。如果要做完整的接口测试,还是尽量使用已经成熟的工具.
PS:简单的造轮子也是学习原理的一个绝佳的方法.
以上这篇基于Python的接口测试框架实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我.
最后此篇关于基于Python的接口测试框架实例的文章就讲到这里了,如果你想了解更多关于基于Python的接口测试框架实例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要开发一个简单的网站,我通常使用 bootstrap CSS 框架,但是我想使用 Gumbyn,它允许我使用 16 列而不是 12 列。 我想知道是否: 我可以轻松地改变绿色吗? 如何使用固定布局
这个问题在这里已经有了答案: 关闭 13 年前。 与直接编写 PHP 代码相比,使用 PHP 框架有哪些优点/缺点?
我开发了一个 Spring/JPA 应用程序:服务、存储库和域层即将完成。 唯一缺少的层是网络层。我正在考虑将 Playframework 2.0 用于 Web 层,但我不确定是否可以在我的 Play
我现有的 struts Web 应用程序具有单点登录功能。然后我将使用 spring 框架创建一个不同的 Web 应用程序。然后想要使用从 struts 应用程序登录的用户来链接新的 spring 应
我首先使用Spark框架和ORMLite处理网页上表单提交的数据,在提交中文字符时看到了unicode问题。我首先想到问题可能是由于ORMLite,因为我的MySQL数据库的字符集已设置为使用utf8
我有一个使用 .Net 4.5 功能的模块,我们的应用程序也适用于 XP 用户。所以我正在考虑将这个 .net 4.5 依赖模块移动到单独的项目中。我怎样才能有一个解决方案,其中有两个项目针对不同的版
我知道这是一个非常笼统的问题,但我想我并不是真的在寻找明确的答案。作为 PHP 框架的新手,我很难理解它。 Javascript 框架,尤其是带有 UI 扩展的框架,似乎通过将 JS 代码与设计分开来
我需要收集一些关于现有 ORM 解决方案的信息。 请随意编写任何编程语言。 你能谈谈你用过的最好的 ORM 框架吗?为什么它比其他的更好? 最佳答案 我使用了 NHibernate 和 Entity
除了 Apple 的 SDK 之外,还有什么强大的 iPhone 框架可供开始开发?有没有可以加快开发时间的方法? 最佳答案 此类框架最大的是Three20 。 Facebook 和许多其他公司都使用
有人可以启发我使用 NodeJS 的 Web 框架吗?我最近开始从免费代码营学习express js,虽然一切进展顺利,但我对express到底是什么感到困惑。是全栈框架吗?纯粹是为了后端吗?我发现您
您可以推荐哪种 Ajax 框架/工具包来构建使用 struts 的 Web 应用程序的 GUI? 最佳答案 我会说你的 AJAX/javascript 库选择应该较少取决于你的后端是如何实现的,而更多
我有生成以下错误的 python 代码: objc[36554]: Class TKApplication is implemented in both /Library/Frameworks/Tk.
首先,很抱歉,如果我问的问题很明显,因为我没有编程背景,那我去吧: 我想运行一系列测试场景并在背景部分声明了几个变量(我打印它们以仔细检查它们是否已正确声明),第一个是整数,另外两个字符串为你可以看到
在我们承担的一个项目中,我们正在寻找一个视频捕获和录制库。我们的基础工作(基于 google 搜索)表明 vlc (libvlc)、ffmpeg (libavcodec) 和 gstreamer 是三
我试过没有运气的情况下寻找某种功能来杀死/中断Play中的正常工作!框架。 我想念什么吗?还是玩了!实际没有添加此功能? 最佳答案 Java stop类中没有像Thread方法那样的东西,由于种种原因
我们希望在我们的系统中保留所有重大事件的记录。例如,在数据库可能存储当前用户状态的地方,事件日志应记录对该状态的所有更改以及更改发生的时间。 事件记录工具应该尽可能接近于事件引发器的零开销,应该容纳结
那里有 ActionScript 2.0/3.0 的测试框架列表吗? 最佳答案 2010-05-18 更新 由于这篇文章有点旧,而且我刚刚收到了赞成票,因此可能值得提供一些更新的信息,这样人们就不会追
我有一个巨大的 numpy 数组列表(一维),它们是不同事件的时间序列。每个点都有一个标签,我想根据其标签对 numpy 数组进行窗口化。我的标签是 0、1 和 2。每个窗口都有一个固定的大小 M。
我是 Play 的新手!并编写了我的第一个应用程序。这个应用程序有一组它依赖的 URL,从 XML 响应中提取数据并返回有效的 URL。 此应用程序需要在不同的环境(Dev、Staging 和 Pro
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我是一名优秀的程序员,十分优秀!