python自动化(五)接口自动化:4.接口自动化框架搭建实战 您所在的位置:网站首页 java自动化测试框架搭建 python自动化(五)接口自动化:4.接口自动化框架搭建实战

python自动化(五)接口自动化:4.接口自动化框架搭建实战

2023-08-14 08:20| 来源: 网络整理| 查看: 265

一.业务分析

我们这里以企业微信的添加成员业务为例,来讲解我们的自动化测试框架。 企业微信接口文档: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: "[email protected]" name: "ojbk001" mobile: "13118170001" department: [1] expect: errcode: 0 errmsg: "created" # 成功userid以数字开头 - add_remenber: userid: "[email protected]" name: "ojbk002" mobile: "13118170002" department: [1] expect: errcode: 0 errmsg: "created" # 请求数据只传入正确的userid,name,email,department。 - add_remenber: userid: "[email protected]" name: "ojbk003" email: "[email protected]" department: [1] expect: errcode: 0 errmsg: "created" # 请求数据只传入正确的userid,name,mobile,department。且关联多个部门 - add_remenber: userid: "[email protected]" 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: "[email protected]" 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: "[email protected]" 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: "[email protected]" name: "ojbk017" mobile: "13118170017" department: [1] external_position: "项目经理" expect: errcode: 0 errmsg: "created" # 请求数据只传入正确的userid,name,mobile,department,external_position,positionv。 - add_remenber: userid: "[email protected]" name: "ojbk018" mobile: "13118170018" department: [1] external_position: "项目经理" position: "产品经理" expect: errcode: 0 errmsg: "created" # 请求数据只传入正确的userid,name,mobile,department,address - add_remenber: userid: "[email protected]" name: "ojbk019" mobile: "13118170019" department: [1] address: "四川省南充市营山县" expect: errcode: 0 errmsg: "created" # userid包含其他字符。 - add_remenber: userid: "ojbk0123_-@.##020" name: "ojbk020" mobile: "13118170020" department: [1] expect: errcode: 40003 # userid以特殊字符开头 - add_remenber: userid: "@[email protected]" name: "ojbk021" mobile: "13118170021" department: [1] expect: errcode: 40003 # userid为超长字符 - add_remenber: userid: "@ojbk0123_-@.022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" name: "ojbk022" mobile: "13118170022" department: [1] expect: errcode: 40058 # userid为空 - add_remenber: name: "ojbk023" mobile: "13118170023" department: [1] expect: errcode: 41009 # name为空 - add_remenber: userid: "[email protected]" mobile: "13118170024" department: [1] expect: errcode: 60112 # mobile和email同时为空 - add_remenber: userid: "[email protected]" name: "ojbk025" department: [1] expect: errcode: 60129 # department为空 - add_remenber: userid: "[email protected]" name: "ojbk026" mobile: "13118170026" expect: errcode: 40066 # department为不存在的部门id - add_remenber: userid: "[email protected]" name: "ojbk027" mobile: "13118170027" department: [5] expect: errcode: 40066 # mobile为错误的手机格式(13位) - add_remenber: userid: "[email protected]" name: "ojbk029" mobile: "1311812700029" department: [1] expect: errcode: 0 # mobile为错误的手机格式(10位) - add_remenber: userid: "[email protected]" name: "ojbk030" mobile: "1311817030" department: [1] expect: errcode: 60103 # email为错误的邮箱格式 - add_remenber: userid: "[email protected]" name: "ojbk031" mobile: "13118170031" department: [1] email: "123000@" expect: errcode: 60105 # 重复的userid - add_remenber: userid: "[email protected]" name: "ojbk032" mobile: "13118170032" department: [1] re_add_remenber: userid: "[email protected]" name: "ojbk0321" mobile: "13118170055" department: [1] expect: errcode: 60102 # 重复的mobile - add_remenber: userid: "[email protected]" name: "ojbk033" mobile: "13118170033" department: [1] re_add_remenber: userid: "[email protected]" name: "ojbk0331" mobile: "13118170033" department: [1] expect: errcode: 60104 # 重复的email - add_remenber: userid: "[email protected]" name: "ojbk034" mobile: "13118170034" department: [1] email: "[email protected]" re_add_remenber: userid: "[email protected]" name: "ojbk0341" mobile: "13118170088" department: [1] email: "[email protected]" expect: errcode: 60106 (2)用例的编写

在这里插入图片描述

#! /usr/bin/python # -*- coding: utf-8 -*- # create_time: 2021-02-26 import os import pytest import yaml from api_frame.page_obj.contact_page import ContactPage from api_frame.my_config.config import TESTDATA,LOGGER from api_frame.page_obj.department_page import DepartmentPage from api_frame.page_obj.material_page import MaterialPage class TestAddRmenber: # 获取请求数据 data_path = os.path.join(TESTDATA, "add_remenber.yaml") with open(file=data_path, mode='r', encoding='utf-8') as f: data = yaml.safe_load(f) def setup_class(self): self.contact = ContactPage() self.department = DepartmentPage(session=self.contact.session) self.materia = MaterialPage(session=self.contact.session) @pytest.fixture(params=data) def get_data(self,request): """ 自定义用例的前置后置方法 :param request: :return: """ LOGGER.info('》》》》》》》START TO EXECUTION CASE 》》》》》》') LOGGER.info('GENERATE TEST CASE DATA') # 生成用例的依赖数据 add_department_data = request.param.get('add_department') up_images_data = request.param.get('up_images') re_add_remenber_data = request.param.get('re_add_remenber') if add_department_data: # 是否需要临时生成部门 r = self.department.add_department(add_department_data) department_id = r.json()['id'] assert r.json()['errcode'] == 0 if up_images_data: # 是否需要临时上传图片 r = self.materia.up_image(up_images_data) avatar_mediaid = r.json().get('media_id') assert r.json()['errcode'] == 0 request.param['add_remenber']['avatar_mediaid'] = avatar_mediaid if re_add_remenber_data: # 是否需要创建两个用户 r = self.contact.add_remenber(re_add_remenber_data) assert r.json()['errcode'] == 0 yield request.param LOGGER.info('CLEAR TEST CASE DATA') # 清理用例的依赖数据,及用例数据 if up_images_data: # 清理图片上传数据 self.avatar_mediaid = None if re_add_remenber_data: # 清理多用户数据 re_del_remenber_data = {} re_del_remenber_data['userid'] = re_add_remenber_data.get('userid') r = self.contact.delete_remenber(re_del_remenber_data) assert r.json()['errcode'] == 0 # 清理用例创建的用户 except_data = request.param.get('expect').get("errcode") if except_data == 0: del_remenber_data = {} del_remenber_data['userid'] = request.param.get('add_remenber').get('userid') r = self.contact.delete_remenber(del_remenber_data) assert r.json()['errcode'] == 0 if add_department_data: # 清理department数据 del_department_data = {} del_department_data['id'] = department_id r = self.department.del_department(del_department_data) assert r.json()['errcode'] == 0 LOGGER.error("》》》》》》》END TO EXECUTION CASE 》》》》》》") # @pytest.mark.parametrize("data",data) def test_addremenber(self,get_data): """添加成员接口测试用例""" LOGGER.info('TEST ADD_REMENBER CASE') # 添加成员接口测试 add_remenber_data = get_data.get('add_remenber') r = self.contact.add_remenber(add_remenber_data) # 断言 expect:dict = get_data.get('expect') errcode = expect.get('errcode') errmsg = expect.get('errmsg') if errcode: assert r.json()['errcode'] == errcode if __name__ == "__main__": pytest.main(['-vs','test_add_remenber.py'])

到这里我们的框架基本上就搭建起来了,后续如果有更多的用例可以继续在该框架中补充。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有