apin 一个不用写代码的接口自动化测试框架
Project description
apin(0.1)使用文档
一、apin介绍及安装
1、什么是apin
apin是一个无需写代码,就可以完成接口自动化测试的框架,只需要通过json或yaml文件编写非常简洁的用例数据,即可完成接口自动化测试,并生成自动化测试报告。
apin是柠檬班—木森老师根据多年的自动化工作经验而开发出来的,旨在帮助更多不会写代码的小伙伴掌握接口自动化测试的能力。框架使用起来非常简单,易上手,只需要几个小时就能掌握!
2、安装apin
apin是基于python3.6开发的,安装前请确认你的python版本>3.6
-
安装命令
pip install apin
二、快速入门
1、项目创建
-
创建命令
apin create 项目名
安装好apin之后,打开命令终端输入创建命令,即可在当前路径下创建项目。
cd 切换到项目之中,即可看到如下的项目结构
-
项目文件说明
-
document: apin使用文档
-
casedata: 存放yaml和json格式编写的用例文件
-
testcases:py:存放py编写的用例目录
-
func_tools.py:自定义的函数工具文件
-
setting.py:整个项目的全局配置文件
-
run.py:项目运行入口文件
-
2、用例编写
apin用例编写支持yaml文件,json文件,py文件三种方式,下面通过一个接口的用例demo来快速了解一下
1、接口demo:
-
接口地址:http://httpbin.org/post
-
请求方法:post
-
请求参数类型:application/json
-
请求参数:
参数名 类型 说明 user str 账号 pwd str 密码
2、json编写用例
在项目的casedata目录下,定义一个以test开头的json文件,按照【apin用例编写规范-json】编写用例即可
-
案例
{ "host": "http://api.XXX.com/futureloan/", "Cases": [ { "title": "普通用户注册", "interface": "member/register", "method": "post", "json":{"mobile_phone":"133010121224","pwd":"lemonban"}, "verification": [] } ] }
3、yaml编写用例
在项目的casedata目录下,定义一个以test开头的yaml文件,按照【apin用例编写规范-yaml】编写用例即可
-
案例
# 域名 host: http://api.XXX.com/futureloan/ # 用例数据 Cases: - title: 普通用户注册 interface: member/register method: post json: mobile_phone: ${{user_mobile}} pwd: lemonban
4、py文件编写用例
在testcases目录中定义一个以test开头的py文件,定义一个以Test开头的类,并且继承于apin.core.httptest.HttpCase类,按照【apin用例编写规范-py】编写用例即可
-
案例
from apin.core.httptest import HttpCase class TestStreamV3(HttpCase): host = "http://api.XXX.com/futureloan/" Cases = [ # 用例1:普通用户注册 { 'title': "普通用户注册", 'interface': "member/register", "method": "post", 'json': {"mobile_phone": "${{user_mobile}}", "pwd": "lemonban"}, }, ]
3、用例运行
-
方式1:
终端项目路径下输入命令
apin run
-
方式2
直接使用python运行项目的run.py文件
4、测试报告和日志
-
日志:项目运行完,会自动在项目路径下生成详细的运行日志
-
测试报告:apin的测试报告是基第三方库unittestreport生成的
运行完会在项目目录的reports目录中,自动生成详细的html测试报告。
三、用例编写规范
1、概念介绍:
-
用例集:apin中创建的每一个test开头的用例文件(py,json,yaml),被称之为一个用例集。一个用例集下面可以定义多条测试用例。
-
测试用例: 用例集中Cases字段中的一条数据就是一个测试用例
2、用例集的主要字段介绍
-
host:用例接口的host地址(接口的域名)
-
类型:字符串
-
例:
host = "http://api.lemonban.com/futureloan/"
-
-
headers:指定用例使用的请求头
-
类型:字典
-
例
headers = {"User-Agent": "apin/musen"}
-
-
method:指定用例接口的请求方法
-
类型:字符串
-
例:post,get
-
-
interface:指定用例接口地址(接口url域名后面的部分)
-
类型:字符串
-
-
env: 设置用例集运行环境的局部变量
-
类型:字典
-
例:
env = { "user_mobile": '13109099878', "pwd": 'lemonban' }
-
-
extract:指定用例请求完要提取的变量(详细介绍见:【四、变量提取和引用】)
-
verification:指定用例的断言(详细介绍见:【五、用例断言】)
-
Cases:设置该测试集下的用例(详细介绍见:下一节【用例字段介绍】)
3、用例字段介绍
1、主要字段:
-
用例集中除env字段之外的字段
-
1、用例集中除env和Cases字段之外,上述用例集中的字段,均支持在用例中自定义。
-
2、如果用例中定义了用例集中的字段,就使用自己定义的,没定义则引用 用例集中的。
-
-
title:用例的描述字段(必传字段)
测试报告和日志信息中用例的描述
-
json: 用来传递json类型的请求参数
请求参数类型为:content-type:application/json,使用该字段来传递请求参数
-
data:用来传递表单类型的请求参数
请求参数类型为:content-type: application/x-www-form-urlencoded,使用该字段来传递请求参数
-
params: 用来查询字符串参数
请求参数,以?key=value的形式 拼接在url后面的参数
2、其他字段
除了上述主要字段之外,python中的requests库中的requests.request方法所有的请求参数,均支持在用例中定义字段,
这些字段在大多数情况下都用不到,如果有用到
-
files:接口用于文件上传
请求参数类型为:content-type:application/from-data,使用该字段来传递请求参数,常用语文件上传
-
cookies:请求的cookie信息(apin中同一个用例集会自动化传递cookie,一遍情况下,不需要使用该字段来传递cookie)
-
auth: 用于Basic/Digest/Custom HTTP认证
-
timeout:设置http请求超时时间
-
allow_redirects:是否运行请求重定向
-
proxies:代理请求的
-
stream:是否立即下载响应内容
-
verify:是否进行证书校验(如果要忽略HTTPS请求的证书校验,则将此参数设置为False)
-
cert:指定校验证书的路径
4、用例编写
1、python编写用例
-
步骤一、在testcases目录中定义一个以test开头的py文件,
-
步骤二、在文件中定义一个以Test开头的类,并且继承于apin.core.httptest.HttpCase类
-
步骤三、在类中,编写测试集的字段值
-
字段名 = 字段值
from apin.core.httptest import HttpCase class TestDomeV3(HttpCase): host = "http://api.lemonban.com/futureloan/" headers = {"X-Lemonban-Media-Type": "lemonban.v2"} # 定义测试前置方法 setup_hook = {"timestamp": 'F{get_timestamp()}'} # 预设变量 env = { "user_mobile": 'F{rand_phone("155")}', "admin_mobile": 'F{rand_phone("133")}' } # 结果校验 verification = {"method": "eq", "expected": {'code': 0, "msg": "OK"}, "actual": {'code': 'V{{$..code}}', "msg": "V{{$..msg}}"}}
-
-
步骤四、在Cases字段中编写用例数据
from apin.core.httptest import HttpCase class TestDomeV3(HttpCase): host = "http://api.XXXX.com/futureloan/" headers = {"X-Lemonban-Media-Type": "lemonban.v2"} # 定义测试前置方法 setup_hook = {"timestamp": 'F{get_timestamp()}'} # 预设变量 env = { "user_mobile": 'F{rand_phone("155")}', "admin_mobile": 'F{rand_phone("133")}' } # 结果校验 verification = {"method": "eq", "expected": {'code': 0, "msg": "OK"}, "actual": {'code': 'V{{$..code}}', "msg": "V{{$..msg}}"}} Cases = [ # 用例1:普通用户注册 { 'title': "普通用户注册", 'interface': "member/register", "method": "post", 'json': {"mobile_phone": "${{user_mobile}}", "pwd": "lemonban"}, }, # 用例2:管理员注册 { 'title': "管理员注册", 'interface': "member/register", "method": "post", 'json': {"mobile_phone": "${{admin_mobile}}", "pwd": "lemonban", "type": 0} }, ]
3、yaml编写用例
使用yaml编写用例前 建议先去学习一下yaml的语法
-
步骤一:在casedata中定义一个test开头的yaml文件
-
步骤二:在yaml文件中定义测试集的字段值
# 域名 host: http://api.xxxxx.com/futureloan/ # 请求头 headers: X-Lemonban-Media-Type: lemonban.v2 # 用例前置钩子函数 setup_hook: timestamp: F{get_timestamp()} # 预设运行变量 env: user_mobile: F{rand_phone("155")} admin_mobile: F{rand_phone("133")} # 结果校验字段 verification: method: eq expected: code: 0 msg: OK actual: code: 'V{{$..code}}' msg: 'V{{$..msg}}'
-
步骤三:在Cases字段中编写测试用例
# 用例数据 Cases: - title: 普通用户注册 interface: member/register method: post json: mobile_phone: ${{user_mobile}} pwd: lemonban - title: 管理员注册 interface: member/register method: post json: mobile_phone: ${{admin_mobile}} pwd: lemonban type: 0
4、json编写用例
使用yaml编写用例前 建议先去学习一下json的语法,json文件中字段名都需要使用双引号
-
步骤一:在casedata中定义一个test开头的json文件
-
步骤二:在json文件中定义测试集的字段值
-
步骤三:在json文件中定义测试集的字段值
{ "host": "http://api.XXXXX.com/futureloan/", "headers": {"X-Lemonban-Media-Type": "lemonban.v2"}, "setup_hook": {"timestamp": "F{get_timestamp()}"}, "env": { "user_mobile": "F{rand_phone('155')}", "admin_mobile": "F{rand_phone('133')}" }, "verification": {"method": "eq", "expected": {"code": 0,"msg": "OK"}, "actual": {"code": "V{{$..code}}","msg": "V{{$..msg}}"} }, "Cases": [ { "title": "普通用户注册", "interface": "member/register", "method": "post", "json": { "mobile_phone": "${{user_mobile}}", "pwd": "lemonban" } }, { "title": "管理员注册", "interface": "member/register", "method": "post", "json": { "mobile_phone": "${{admin_mobile}}", "pwd": "lemonban", "type": 0 } } ] }
四、变量提取和引用
变量提取和引用主要是为了解决接口之间的参数依赖问题
使用场景:接口A的参数中需要使用接口B返回的某个数据,那么就要在请求B接口之后,提取数据保存,给请求A接口时使用。
1、变量提取
在用例集或用例数据中,通过extract字段指定要提取的变量。
-
语法
"extract": { "变量名": ("变量保存的级别", "提取方式", "提取表达式"), }
-
变量名:保存数据的变量名
-
变量保存的级别:
-
EVN: 全局变量,settings文件中的EVN
-
env : 为局部变量(只对当前用例集有效):用例集的env字段
-
-
提取方式
-
re: 正则表达式提取
-
jsonpath: 通过jsonpath提取
-
-
-
案例
"extract": { # 通过jsonpath提取 "token": ("env", "jsonpath", "$..token"), # 通过正则表达式提取 'member_id': ("env", "re", r'"id":(.+?),') }
2、变量引用
-
变量引用表达式:${{变量名}}
-
引用优先级
优先引用该用例的局部变量(用例的env中的变量),如果局部变量不存在,则会引用全局变量(setting.py中ENV中保存的变量)。
五、用例断言
关于测试用例预期结果和实际结果的比对的,apin中封装了一个verification字段,只需要在verification中定义预期结果,实际结果提取表达式,和断言的方法,即可实现用例的断言!
1、基本语法
verification = [
[断言方式, 预期结果, 实际结果]
]
2、断言方式
apin中目前支持两种断言方式:
-
1、断言相等 :eq
预期结果和实际结果相等
verification = [ ['eq', 预期结果, 实际结果] ]
-
2、断言包含:contians
实际结果中包含预期结果的内容
verification = [ ['contians', 预期结果, 实际结果] ]
3、实际结果获取
关于断言的实际结果提取,需要使用V{{表达式}}
来进行提取,表达式支持jsonpath和正则表达式两种提取方式方式。
-
1、正则表达式提取
# 通过正则表达式来提取实际结果中的msg字段。 verification = [ ['contians', {'msg':"OK"}, {"msg": "V{{msg:'(.+?)'}}"}] ]
-
2、通过jsonpath提取
# 通过jsonpath来提取实际结果中的msg字段。 verification = [ ['contians', {'msg':"OK"}, {"msg": 'V{{$..msg}}'] ]
4、HTTP状态码的断言
上述两种方式,以可提取结果返回的数据,那如果要断言接口http请求的状态码呢?apin中也提供了一个内置的字段名,来表示http状态码
# 断言接口请求的http状态码是否等于200
verification = [
['eq', 200, 'status_code']
]
六、函数工具的使用
apin支持在测试用例中调用自定义的函数来处理数据,如对数据进行加密处理、随机生成数据等等。
1、自定义函数
apin创建的项目中有一个funcTools.py,在该文件中可以自己定义函数,然后在用例中通过F{xxx()}来调用。
-
案例:funcTools.py文件
import hashlib,random
def md5_encrypt(msg):
"""md5加密"""
md5 = hashlib.md5()
md5.update(msg.encode("utf8"))
return md5.hexdigest()
def rand_phone():
"""随机生成手机号的函数"""
import random
for i in range(8):
phone += str(random.randint(0, 9))
return str(phone)
def get_timestamp():
"""获取时间戳"""
return time.time()
-
注意点:函数处理完的数据需要return返回哦
2、用例中引用函数
-
引用表达式:F{函数名()}
-
demo1:用例数据中的user,引用前面定义的rand_phone函数
{
'title': "普通用户注册",
'interface': "member/register",
"method": "post",
'json': {"user": "F{rand_phone()}", "pwd": "lemon123"},
}
-
demo2:用例数据中的pwd,引用前面定义的md5_encrypt函数对密码进行md加密
- 注意点:引用的函数,传递的参数如果是变量,则不需要在变量应用表达式外加引号
{
'title': "普通用户登录",
'interface': "member/login",
"method": "post",
'json': {"user": "13109877890", "pwd": "F{md5_encrypt('lemon123')}"},
}
# 引用函数,变量作为参数传递
{
'title': "普通用户登录",
'interface': "member/login",
"method": "post",
'json': {"user": "${{user}}", "pwd": "F{md5_encrypt(${{pwd}})}"},
}
七、项目全局配置
项目中的setting.py文件,是整个项目的配置文件,接下来相信介绍一下项目的配置选项。
1、debug模式运行
项目创建之后,默认运行是开启了debug模式,运行过程中会输出详细的debug级别日志。如果不像看运行日志,则将settings中的DEBUG设置为Flase即可。
# 是否开启debug模式:True为debug模式,False为关闭debug模式
DEBUG = False
2、ENV全局的变量
将settings.py中的ENV可以设置项目全局配置,
-
全局的域名
推荐在ENV中设置全局的host,不建议在每一个测试用例中去设置host,切换测试环境切换也更方便(如果用例数据中没有自己定义host,会自动引用全局的host地址)
ENV = { "host":"http://WWW.XXX.com/", }
-
全局的请求头
如果项目接口有必传的请求头数据,也可以直接在ENV中设置(如果用例数据中没有定义时,也会自动引用全局的headers)。
ENV = { "host":"http://WWW.XXX.com/", "headers": {"UserAgent": "apin-test01"} }
-
全局的测试数据
如果用例中需要引用事先准备好的一些测试数据,如测试账号、密码之类的
如:定义一个测试账号、测试密码、用户id
ENV = { "host":"http://WWW.XXX.com/", "headers": {"UserAgent": "apin-test01"}, "user":"musen@qq.com", "pwd":"lemon123", "user_id":111 }
测试用例中直接使用${{}}即可引用,
# 引用user和pwd { 'title': "登录", 'interface': "member/register", "method": "post", 'json': {"mobile_phone": "${{user}}", "pwd": "${{pwd}}"}, }
-
注意点:如果局部环境和全局变量重名,优先引用局部变量。
-
3、测试报告
通过setting中的TEST_RESULT,可以配置测试报告的输出信息。
TEST_RESULT = {
# 测试报告文件名
"filename": "report.html",
# 测试人员
"tester": "测试员",
# 报告标题
"title": "测试报告",
# 报告样式 :有1,2,三个样式
"templates": 1,
# 报告描述信息
"desc": "XX项目测试生成的报告"
}
4、邮件推送测试结果
如果要将测试结果发送到指定的邮箱中,则在settings.py添加EMAIL配置即可
EMAIL = {
# smtp服务器地址
"host": 'smtp.qq.com',
# smtp服务器端口
"port": 465,
# 邮箱账号
"user": "xxxx@qq.com",
# smtps授权码
"password": "xxxx",
# 收件人列表
"to_addrs": ['xxx@qq.com','xxx@qq.com'],
# 是否发送附件
"is_file": True
}
5、测试结果推送到钉钉群
如果要将测试结果推送到钉钉群,则在settings.py添加DINGTALK配置即可。
DINGTALK = {
# 钉钉机器人的Webhook地址
"url": "",
# 如果钉钉机器人安全设置了关键字,则需要传入对应的关键字
"key": None,
# 如果钉钉机器人安全设置了签名,则需要传入对应的密钥
"secret": None,
# 钉钉群中要@人的手机号列表,如:[137xxx,188xxx]
"atMobiles": [],
# 是否@所有人
"isatall": False
}
6、测试结果推送企业微信群
如果要将测试结果推送到企业微信群,则在settings.py添加WECHAT配置即可。
WECHAT = {
# 企业微信群ID
"chatid": "",
# 调用企业微信API接口的凭证
"access_token": ""
}
八、用例前后置执行
关于测试用例执行的前后置,apin中提供了四个字段来指定用例前后置执行的函数。
1、setup_hook
-
指定用例 的前置执行函数
# 设置一个用例级别的前置函数,将前置函数的返回值,保存到局部变量的timestamp setup_hook = {"timestamp": 'F{get_timestamp()}'}
2、setup_class_hook
-
指定用例集 的前置执行函数
# 设置一个测试集级别的前置函数,将前置函数的返回值,保存到局部变量的timestamp setup_class_hook = {"timestamp": 'F{get_timestamp()}'}
3、teardown_hook
-
指定用例 的后置执行函数
# 设置一个用例级别的后置 teardown_hook = {"teardowm": 'F{data_clear()}'}
4、teardown_class_hook
-
指定用例集的后置执行函数
# 设置一个测试集级别的后置方法 teardown_hook = {"teardowm": 'F{data_clear()}'}
1
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file apin-0.1.tar.gz
.
File metadata
- Download URL: apin-0.1.tar.gz
- Upload date:
- Size: 66.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | b0170c80adc1bf73b5084671ac8e4d0952bf62f7e10862f24dc384b09be788b6 |
|
MD5 | 2892e327fadf22e7b0d2364a2c72e00b |
|
BLAKE2b-256 | 5dd7547a724a6846348bf09d839d034b94bf92690c202e16c733044eeceea624 |
File details
Details for the file apin-0.1-py3-none-any.whl
.
File metadata
- Download URL: apin-0.1-py3-none-any.whl
- Upload date:
- Size: 74.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 58feddb85d25789fd3e9b31515e32775336c68456c7071a5446bd5acc1082810 |
|
MD5 | 0f2a38c8da990985f557c15943cc6137 |
|
BLAKE2b-256 | ea742e8ddca9bc673bc534fbc6fd644af019988cb984343101c1f46b1679396a |