最近要开展接口测试,起初打算使用公司已有的Fitnesse测试工具来进行接口测试。过程中发现,构造接口字段数据、测试数据都比较困难,接口参数多的时候,用例量就会很多,关键执行速度还慢。所以放弃了。

找了一些其它工具,都不太能解决数据构造困难的问题。找不到工具,就直接使用代码来实现。考虑到代码量,结合网上的一些推荐,决定使用python+pytest来编写接口自动化用例。

决定了语言和框架,接下来要考虑一下实现需求。

1.一套用例可以测试多套环境

2.可以被jenkins调度执行

3.拥有测试报告

4.接口中某些字段值在每次请求中不重复

5.可以多接口关联测试

6.构造的表数据可以和接口字段数据关联

7.pytest用例和实际用例数据要分离,方便维护

8.针对多样的响应内容,具备多样的断言方式。


需求一:一套用例可以测试多套环境

公司的测试环境不止一套,希望在使用接口自动化用例时,可以随意的切换被测环境。

为了满足这个需求,首先要完成接口地址等信息的独立配置,而且是要按照一套环境的维度去管理信息。

我的做法如上图,首先我给每套环境设置了一个别名,比如上图中的lion环境,然后设计了一个服务去持久化变量值信息(变量名称所有环境保存一致)。

接着将环境名称和变量名称,组合起来,保存到redis中(如上图),供后续接口自动化用例读取并使用。

环境信息搞定之后,接下来的任务就是,设计一种方法让接口自动化用例使用环境信息。

这里采用的方法是,在执行时,指定环境别名。

pytest的用例有多种执行方式,这里使用pytest.main()来启动,通过将pytest.main()写入一个py文件中,如下面代码。


memberCenter.py
1 if __name__ == "__main__":
if (len(sys.argv) == 2):
_, env = sys.argv
else:
env = 'lion'
BaseUtil.initTest(env)
pytest.main(['--alluredir=./allure-results', '--maxfail=5','-s','-rA', 'testcase/membercenter/'])

启动时,接受一个参数env,并将env作为属性添加到Context中,供用例使用。

BaseUtil.py
from context import Context as ct
def initTest(env):
ct.env = env 

调用命令:

这里就指定了测试环境的别名为lion。

有了环境别名,再加上统一的变量名称,就可以使用下面的方式,去redis获取对应的变量值了。

以上就实现了多环境测试的需求。后续只要维护好环境别名、变量名称和变量值就可以了。


需求二: 可以被jenkins调度执行

这个比较简单,通过参数化构建就可以。

不过为了不影响Jenkins所在服务器,我使用了docker去执行用例

下面是Dockerfile的配置

下面是jenkins中的Execute shell

 echo "清除历史报告记录"
cd ${WORKSPACE}
cd allure-report && rm -rf *
cd ${WORKSPACE}
cd allure-results && rm -rf * echo "开始执行命令"
cd ${WORKSPACE} function del_ci {
echo "$1"
docker stop chbifacetest
docker rm chbifacetest
docker rmi hbifacetest:1.1
} docker inspect --format '{{.State.Running}}' chbifacetest && del_ci "删除容器和镜像" docker build -t hbifacetest:1.1 .
docker run -v ${WORKSPACE}/allure-results:/usr/local/hbifacetest/allure-results -v ${WORKSPACE}/allure-report:/usr/local/hbifacetest/allure-report --name chbifacetest hbifacetest:1.1 ${pymainfile} ${testEnv}
echo "执行结束"

需求三  拥有测试报告

测试报告使用的是Allure,主要是美观且配置简单,(参考:https://docs.qameta.io/allure/#_pytest)

step1:配置报告路径

添加一个参数--alluredir=./allure-results

step2:编写用例时,添加注释

step3:在jenkins中安装插件

step4:在job中配置报告路径

step5:在另一个job中添加执行计划

step6:查看报告


需求四:接口中某些字段值在每次请求中不重复


这里通过python的一个库factory-boy来实现该需求。(参考:https://www.cnblogs.com/moonpool/p/11352705.html)

大概的原理就是将每个接口当做一个对象来处理,通过factory-boy给每个字段添加值,可以是固定值,也可以是随机值。然后将对象转成dict,并发送请求。(复杂对象转dict比较麻烦,参考:https://www.cnblogs.com/moonpool/p/11454902.html)

如下图中的红框部分字段,每次请求都将是不同的值。


需求五: 可以多接口关联测试

针对这个需求,实现的主要思路是,可以在一条Pytest用例中,拿到所有接口的请求和响应参数。

这里利用了pytest中fixture,将每个接口的http请求方法封装成fixture,后续传递给pytest用例使用。同理实现了 加载用例数据的Fixture

 #接口Fixture
@pytest.fixture(scope="function")
def member_borrower_addBorrower_http_json():
def _member_borrower_addBorrower_http_json(dict={"key": "value"}):
r = ht.post_json(url=member_borrower_addBorrower_url, json=dict,headers=headers_json)
return r return _member_borrower_addBorrower_http_json @pytest.fixture(scope="function")
def member_borrower_updateBorrower_http_json():
def _member_borrower_updateBorrower_http_json(dict={"key": "value"}):
r = ht.post_json(url=member_borrower_updateBorrower_url, json=dict,headers=headers_json)
return r return _member_borrower_updateBorrower_http_json #加载用例数据的Fixture
@pytest.fixture(scope="function",params=addBorrower)
def test_member_borrower_addBorrower(request):
dict=request.param
return dict @pytest.fixture(scope="function",params=updateBorrower)
def test_member_borrower_updateBorrower(request):
dict=request.param
return dict

下面是用例数据,可以看到request中传递的是一个函数,函数执行后,可以拿到两个请求的请求参数。

下面的是pytest用例,可以看到用例中可以同时维护两个请求接口的请求参数和响应内容

这里例子比较简单,更新请求中,需要使用到添加响应中的data字段值。


需求六 构造的表数据可以和接口字段数据关联

有时候没有办法,通过其它接口的调用得到的信息,来为当前测试接口做数据入参。可偏偏需要在数据库中存在数据,才可以调用当前测试接口。

可以利用Factory-boy和sqlalchemy来实现这个需求。利用Factory-boy生成随机数据,利用sqlalchemy将数据入库。

例如下面pytest用例的红框部分,就是在插入数据,并使用数据中black_index,作为当前测试接口的请求入参

下面是CreateMBL函数的实现

下面是Factory-boy生成数据的代码  (参考:https://www.cnblogs.com/moonpool/p/11370502.html)

 import factory
import factory.fuzzy
from sqlalchemy import Column,String,BIGINT,INT,VARCHAR,DECIMAL, Unicode, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from .dbsession import FintechDBSession
from baseutil.pr import Provider Base = declarative_base() class member_black_list(Base):
# 表的名字:
__tablename__ = 'member_black_list' # 表的结构:
black_index=Column(BIGINT(), primary_key=True)
black_type=Column(INT())
real_name=Column(VARCHAR(120))
card_id=Column(VARCHAR(40))
phone=Column(VARCHAR(40))
remark=Column(VARCHAR(1024))
oper_id=Column(VARCHAR(40))
oper_name=Column(VARCHAR(255))
create_time = Column(VARCHAR(14))
update_time=Column(VARCHAR(14))
status=Column(INT())
reason=Column(VARCHAR(512))
examine_status=Column(INT())
effective_start_date=Column(VARCHAR(8))
effective_end_date=Column(VARCHAR(8))
black_source=Column(INT())
version=Column(INT()) factory.Faker.add_provider(Provider) class member_black_list_factory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = member_black_list
sqlalchemy_session = FintechDBSession black_index = factory.Faker("randomInt")
black_type = 1
real_name = factory.Faker("name", locale="zh_CN")
card_id = factory.Faker("idNumber")
phone = factory.fuzzy.FuzzyText("", 6, "", "")
remark = "自动化接口测试"
oper_id = ""
oper_name = "test1234"
create_time = factory.Faker("currentTimeByFormat")
update_time = factory.Faker("currentTimeByFormat")
status = 1
reason = "自动化接口测试"
examine_status = 1
effective_start_date = factory.Faker("datebyday", days=0, ft="%Y-%m-%d")
effective_end_date = factory.Faker("datebyday", days=1, ft="%Y-%m-%d")
black_source = 0
version = 0

需求七 pytest用例和实际用例数据要分离,方便维护

在需求五中依据可以看出, pytest用例和实际用例数据是分离。

大部分接口自动化做法是使用excel去维护用例,但是当接口或响应字段比较多的时候,编写用例比较麻烦。如果出现接口字段变更,修改用例也变得比较麻烦。

首先pytest用例和实际用例分离是必须的,接下来就是怎么维护用例的问题。

下面就是我的实际用例数据,可以看到request中通过不同的参数,可以生成不同的请求数据。至于怎么执行用例,参考https://www.cnblogs.com/moonpool/p/11351859.html


需求八 针对多样的响应内容,具备多样的断言方式

 

起初在用例的response中,只存放了一个dict,如下图,但是有时候响应内容(json格式)是多样的,需要断言的字段不一定都在json的顶层结构中,可能还会出现嵌套dict以及list的情况。

下面是我的实现。主要的思想就是根据不同的断言需求,传递给不同的断言方法。

用例中调用下面的函数,可以生成一批断言集合。

当断言需求类型是dict的时候,会调用下面的函数。

用例response编写,指定不同的断言需求

pytest 用例使用,如红框部分,结合上面的用例的断言需求,在用例执行时,实时传入实际响应内容。再遍历执行断言函数集合。就完成了多样的断言需求。

基于pytest的接口测试的更多相关文章

  1. 基于LoadRunner构建接口测试框架

    基于LoadRunner构建接口测试框架 http://www.docin.com/p-775544153.html

  2. 【转】基于Python的接口测试框架实例

    下面小编就为大家带来一篇基于Python的接口测试框架实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧   背景 最近公司在做消息推送,那么自然就会产生很多接口,测试 ...

  3. Appium 并发多进程基于 Pytest框架

    前言: 之前通过重写unittest的初始化方法加入设备参数进行并发,实现了基于unittest的appium多设备并发,但是考虑到unittest的框架实在过于简陋,也不方便后期的Jenkins的持 ...

  4. 基于python的接口测试框架设计(三)接口测试的框架

    基于python的接口测试框架设计(三)接口测试的框架 其实我这里用到的是unittest单元测试框架,,这个框架好就好在比较清楚,,setup terdown都可以处理一些初始化及完成后的工作 主要 ...

  5. 基于python的接口测试框架设计(二)配置一些参数及文件

    基于python的接口测试框架设计(二)配置一些参数及文件 我这里需要基于我的项目配置的主要是登陆参数.以及baseURL ,把这些放在单独的文件里  毕竟导入的时候方便了一些 首先是url 图略 建 ...

  6. 基于python的接口测试框架设计(一)连接数据库

    基于python的接口测试框架设计(一)连接数据库 首先是连接数据库的操作,最好是单独写在一个模块里, 然后便于方便的调用,基于把connection连接放在__init__()方法里 然后分别定义D ...

  7. 基于Python的接口测试框架实例

    文章来源:http://www.jb51.net/article/96481.htm 下面小编就为大家带来一篇基于Python的接口测试框架实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. ...

  8. 基于HTTPS的接口测试——nginx配置SSL

    目录 基于HTTPS的接口测试--nginx配置SSL 1. 背景 2. 所需环境与域名备案解析 2.1 云服务器 2.2 域名 2.3 SSL证书 2.4 网站备案 2.5 域名解析 3.nginx ...

  9. 基于Pytest豆瓣自动化测试【1】

    -- Pytest基础使用教程[1] 引言 Pytest 是一个非常实用的自动化测试框架,目前来说资料也是非常多了.最近某友人在学习 Python的一些测试技术,帮其网上搜了下教程:发现大多数文章多是 ...

随机推荐

  1. CSS或HTML如何实现文字下面加点?

    就像word里文字加着重号一样,在字的下面加一个点,用CSS怎么做?注意,我说的是下面加点,不是文字加粗或倾斜,请不要回答<strong>或<em>之类的. 把要着重加点的文字 ...

  2. exiftool(-k)与gui的联合使用

    首先下载一个exiftool下载后改名字https://sno.phy.queensu.ca/~phil/exiftool/ 根据自己的操作系统选择,我需要这个 然后下载guihttp://u88.n ...

  3. HTML5定位功能,实现在百度地图上定位

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Luogu P4782 【模板】2-SAT 问题(2-SAT)

    P4782 [模板]2-SAT 问题 题意 题目背景 \(2-SAT\)问题模板 题目描述 有\(n\)个布尔变量\(x_1\sim x_n\),另有\(m\)个需要满足的条件,每个条件的形式都是&q ...

  5. 微信回调校验失败兼容php7

    今天在移动微信支付的代码的时候,发现校验失败,之前好好的,一点点打印了,顺着微信校验程序打印看结果,发现  $xml = $GLOBALS['HTTP_RAW_POST_DATA'];; 接收到的数据 ...

  6. Linux产生coredump文件(core)

    1.可以使用命令 ulimit -c unlimited 来开启 core dump 功能,并且不限制 core dump 文件的大小: 如果需要限制文件的大小,将 unlimited 改成你想生成 ...

  7. Android实战技巧之四十一:制作自己的Android SDK

      标签: sdkandroid定制sdk 2015-09-21 18:05 11237人阅读 评论(2) 收藏 举报  分类: Android(260)  版权声明:本文为博主原创文章,未经博主允许 ...

  8. jeecms框架单点登录功能的实现

    单点登录的功能实现主要原理: 1: 在点击登录按钮的时候使用reponse.addCookie()方法向浏览器发送cookie: 2: 在前段拦截器中的request.getCookie()在接收到设 ...

  9. 深喉起底APP线下预装市场,如何一夜间拥有千万用户

    注:预装对于中国的移动互联网创业者有多重要?i黑马知道这样一个内幕,某商务告诉我他们公司的前2000万用户就是靠预装打下来的,总部在北京,直接派驻商务长期扎根在深圳搞定手机厂商.而这家公司初期发展得益 ...

  10. 第一个SpringBoot插件-捕获请求并且支持重新发起

    SpringBoot 插件入门 简介 公司用的是SpringBoot,api框架用的是swagger-ui,确实用的不错,但是在使用过程中发现一个问题,就是当前端正式调用的时候,如果参数一多的话模拟请 ...