python自动化接口自动化:4.接口自动化框架搭建实战
Posted new nm个对象
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python自动化接口自动化:4.接口自动化框架搭建实战相关的知识,希望对你有一定的参考价值。
一.业务分析
我们这里以企业微信的添加成员业务为例,来讲解我们的自动化测试框架。
企业微信接口文档:https://work.weixin.qq.com/api/doc/90000/90135/90195
二.框架搭建实战
1.框架目录结构分析
- data:存放测试用例数据的目录。
- images:存放项目图片的目录。
- logs:存放日志文件的目录。
- my_config:存放配置文件的目录。
- my_tools:存放公共方法代码的位置。
- page_obj:存放page类代码的目录。
- test_case:存放用例代码的位置
2.公共方法封装
(1)获取项目根路径方法封装
#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
def get_base_dir():
"""
获取项目根目录
:return:
"""
now_dir = os.getcwd()
while True:
now_dir_list = os.path.split(now_dir)
now_dir = now_dir_list[0]
if now_dir_list[1] == "xiongxiong_test_frame":
now_dir = os.path.join(now_dir_list[0], now_dir_list[1])
break
return os.path.join(now_dir,'api_frame')
if __name__ == "__main__":
print(get_base_dir())
(2)日志方法封装
#! /usr/bin/python
# -*- coding: utf-8 -*-
import logging
class GetLog:
"""
自定义logging类
方法:1.get_logger:获取一个Logger对象。
"""
def get_logger(self, name, level, fromt, path):
"""
获取Logger对象。
:param name: Logger名字。
:param level: Logger级别。
:param fromt: Logger日志输出级别。
:param path: 日志文件路径。
:return: Logger对象
"""
self.logger = logging.getLogger(name=name)
self.logger.setLevel(logging.DEBUG)
if not self.logger.hasHandlers():
# 给Logger添加一个FileHandler
file_handler = logging.FileHandler(filename=path,encoding='utf-8')
file_handler.setLevel(level=level)
file_handler.setFormatter(fmt=fromt)
self.logger.addHandler(file_handler)
# 给Logger添加一个FileHandler
stream_handler = logging.StreamHandler()
stream_handler.setLevel(level=level)
stream_handler.setFormatter(fmt=fromt)
self.logger.addHandler(stream_handler)
return self.logger
(3)当前时间串方法封装
#! /usr/bin/python
# -*- coding: utf-8 -*-
from datetime import datetime
def get_now_time():
"""
获取当前时间字符串
:return:
"""
now = datetime.now().strftime('%Y-%m-%d-%H%M%S')
return now
if __name__ == "__main__":
print(get_now_time())
3.配置文件的使用
#! /usr/bin/python
# -*- coding: utf-8 -*-
# create_time: 2021-02-22
import logging
import os
from api_frame.my_tools.get_dir import get_base_dir
## 目录配置
# 项目目录
BASEDIR = get_base_dir()
# 临时图片目录
IMAGESDIR = os.path.join(BASEDIR,"images")
# 测试数据目录
TESTDATA = os.path.join(BASEDIR,"data/contact_data")
## 日志配置
import os
from api_frame.my_tools.get_log import GetLog
from api_frame.my_tools.get_strtime import get_now_time
LOG_NAME = 'ROOT'
LOG_PATH = os.path.join(BASEDIR,f'logs/{get_now_time()}.log')
LOG_LEVEL = logging.INFO
LOG_FORMAT = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s-%(filename)s-%(lineno)d-%(funcName)s')
# 实例化以后Logger对象
LOGGER = GetLog().get_logger(name=LOG_NAME, level=LOG_LEVEL, fromt=LOG_FORMAT, path=LOG_PATH)
4.pageobje类的封装
注意:我们本次虽然只测试添加成员接口,但该接口的用例对删除成员,添加部门,删除部门等接口有数据依赖,所以也需要将这些接口封装到page类中。
basepage基类封装
#! /usr/bin/python
# -*- coding: utf-8 -*-
# createtime: 2021-02-01
import requests
from requests import Session
class BasePage:
def __init__(self,corpid=None,corpsecret=None,session=None):
# 生成session
if session:
self.session = session
else:
if corpid is None:
my_corpid = 'wwb0963a3a379de433'
else:
my_corpid = corpid
if corpsecret is None:
my_corpsecret = 'X-G73KTHX9is69sJcNbv-T80SyqL86EyvFUOpm4MTsg'
else:
my_corpsecret = corpsecret
r = requests.get(url=f'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={my_corpid}&corpsecret={my_corpsecret}')
token = r.json()['access_token']
self.session = Session()
# 将token封装到session
self.session.params['access_token'] = token
成员模块相关接口封装
#! /usr/bin/python
# -*- coding: utf-8 -*-
# createtime: 2021-02-01
import os
from typing import List
from api_frame.my_config.config import BASEDIR,LOGGER
from api_frame.page_obj.base_page import BasePage
class ContactPage(BasePage):
"""
通讯录管理相关接口封装
"""
def add_remenber(self,add_remenber:dict=None):
"""
添加成员接口封装
:param add_remenber: 添加成员接口请求数据
:return: 接口返回对象
"""
try:
# 获取请求数据
json_data = add_remenber
# 发送请求
r = self.session.post(url='https://qyapi.weixin.qq.com/cgi-bin/user/create',json=json_data)
LOGGER.info('Access to "add_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/create success')
return r
except Exception as e:
LOGGER.error('Access to "add_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/create failed')
raise e
def find_remenber(self,userid):
"""
查询成员接口封装
:param userid: 成员UserID。对应管理端的帐号,企业内必须唯一。不区分大小写,长度为1~64个字节
:return: 接口返回对象
"""
try:
params = {
"userid": userid
}
r = self.session.get(url='https://qyapi.weixin.qq.com/cgi-bin/user/get',params=params)
LOGGER.info('Access to "find_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/get success')
return r
except Exception as e:
LOGGER.error('Access to "find_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/get failed')
raise e
def delete_remenber(self,delete_remenber_data:dict):
"""
删除成员接口封装
:param delete_remenber_data: 成员UserID。对应管理端的帐号,企业内必须唯一。不区分大小写,长度为1~64个字节
:return: 接口返回对象
"""
try:
params = delete_remenber_data
r = self.session.get(url='https://qyapi.weixin.qq.com/cgi-bin/user/delete',params=params)
LOGGER.info('Access to "delete_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/delete success')
return r
except Exception as e:
LOGGER.error('Access to "delete_remenber" url https://qyapi.weixin.qq.com/cgi-bin/user/delete failed')
raise e
部门管理接口封装
#! /usr/bin/python
# -*- coding: utf-8
# create_time: 2021-02-24
from api_frame.my_config.config import LOGGER
from api_frame.page_obj.base_page import BasePage
class DepartmentPage(BasePage):
"""部门管理page类"""
def add_department(self,add_department:dict):
"""
添加部门接口封装
:param add_department: 添加部门请求参数
:return: 接口响应对象
"""
try:
# 生成请求数据
json_data = add_department
# 发送请求
r = self.session.post("https://qyapi.weixin.qq.com/cgi-bin/department/create",json=json_data)
LOGGER.info('Access to "add_department" url https://qyapi.weixin.qq.com/cgi-bin/department/create success')
return r
except Exception as e:
LOGGER.error('Access to "add_department" url https://qyapi.weixin.qq.com/cgi-bin/department/create failed')
raise e
def del_department(self,del_deparment:dict):
"""
删除部门接口封装
:param del_deparment: 删除部门请求参数
:return: 接口响应对象
"""
try:
# 生成请求数据
json_data = del_deparment
# 发送请求
id = del_deparment.get('id')
r = self.session.get(url=f"https://qyapi.weixin.qq.com/cgi-bin/department/delete?id={id}")
LOGGER.info(f'Access to "del_department" url https://qyapi.weixin.qq.com/cgi-bin/department/delete?id={id} success')
return r
except Exception as e:
LOGGER.error(
f'Access to "del_department" url https://qyapi.weixin.qq.com/cgi-bin/department/delete?id={id} failed')
raise e
素材管理接口封装
#! /usr/bin/python
# -*- coding: utf-8
# create_time: 2021-02-24
import os
from api_frame.page_obj.base_page import BasePage
from api_frame.my_config.config import BASEDIR,IMAGESDIR,LOGGER
class MaterialPage(BasePage):
"""素材管理page类"""
def up_image(self,filename:dict):
"""
上传图片
:return:
"""
try:
filename = filename.get('filename')
filedir = os.path.join(IMAGESDIR,filename)
with open(file=filedir,mode='rb') as f:
file = {"file": f}
r = self.session.post("https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=image",files=file)
LOGGER.info(
f'Access to "up_image" url https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=image success')
return r
except Exception as e:
LOGGER.error(
f'Access to "up_image" url https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=image failed')
raise e
if __name__ == "__main__":
s = MaterialPage().up_image("my_wework.png")
print(s.json())
5.测试用例的编写
在page类封装完成后,我们便可以使用page类中的方法来编写测试用例。编写用例时需要注意用例数据的独立性,数据在用例中生成,且用例完成后将遗留数据清除。
(1)数据文件编写
# 成功userid以字母开头
- add_remenber:
userid: "ojbk0123_-@.001"
name: "ojbk001"
mobile: "13118170001"
department: [1]
expect:
errcode: 0
errmsg: "created"
# 成功userid以数字开头
- add_remenber:
userid: "77ojbk0123_-@.002"
name: "ojbk002"
mobile: "13118170002"
department: [1]
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,email,department。
- add_remenber:
userid: "ojbk0123_-@.003"
name: "ojbk003"
email: "1230001@qq.com"
department: [1]
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department。且关联多个部门
- add_remenber:
userid: "ojbk0123_-@.004"
name: "ojbk004"
mobile: "13118170004"
department: [1,2]
add_department:
name: "ojbk004"
parentid: 1
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,alias
- add_remenber:
userid: "ojbk0123_-@005"
name: "ojbk005"
mobile: "13118170005"
department: [1]
alias: "ojbk005"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,order。
- add_remenber:
userid: "ojbk0123_-@006"
name: "ojbk006"
mobile: "13118170006"
department: [1]
order: 1
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,position。
- add_remenber:
userid: "ojbk0123_-@007"
name: "ojbk007"
mobile: "13118170007"
department: [1]
position: "产品经理"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,gender。
- add_remenber:
userid: "ojbk0123_-@008"
name: "ojbk008"
mobile: "13118170008"
department: [1]
gender: 1
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,gender
- add_remenber:
userid: "ojbk0123_-@009"
name: "ojbk009"
mobile: "13118170009"
department: [1]
gender: 2
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,email。
- add_remenber:
userid: "ojbk0123_-@010"
name: "ojbk010"
mobile: "13118170010"
department: [1]
email: "123010@qq.com"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,telephone。
- add_remenber:
userid: "ojbk0123_-@011"
name: "ojbk011"
mobile: "13118170011"
department: [1]
telephone: "0519-000011"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,is_leader_in_dept。
- add_remenber:
userid: "ojbk0123_-@012"
name: "ojbk012"
mobile: "13118170012"
department: [1]
is_leader_in_dept: 0
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,is_leader_in_dept。
- add_remenber:
userid: "ojbk0123_-@.013"
name: "ojbk013"
mobile: "13118170013"
department: [1]
is_leader_in_dept: 1
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,avatar_mediaid。
- add_remenber:
userid: "ojbk0123_-@014"
name: "ojbk014"
mobile: "13118170014"
department: [1]
up_images:
filename: my_wework.png
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,enable。
- add_remenber:
userid: "ojbk0123_-@015"
name: "ojbk015"
mobile: "13118170015"
department: [1]
enable: 0
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,enable
- add_remenber:
userid: "ojbk0123_-@016"
name: "ojbk016"
mobile: "13118170016"
department: [1]
enable: 1
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,external_position。
- add_remenber:
userid: "ojbk0123_-@.017"
name: "ojbk017"
mobile: "13118170017"
department: [1]
external_position: "项目经理"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,external_position,positionv。
- add_remenber:
userid: "ojbk0123_-@.018"
name: "ojbk018"
mobile: "13118170018"
department: [1]
external_position: "项目经理"
position: "产品经理"
expect:
errcode: 0
errmsg: "created"
# 请求数据只传入正确的userid,name,mobile,department,address
- add_remenber:
userid: "ojbk0123_-@.019"
name: "ojbk019"
mobile: "13118170019"
department: [1]
address: "四川省南充市以上是关于python自动化接口自动化:4.接口自动化框架搭建实战的主要内容,如果未能解决你的问题,请参考以下文章