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.接口自动化框架搭建实战的主要内容,如果未能解决你的问题,请参考以下文章

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

Python 基于http接口自动化测试

python结合excel数据轻松实现接口自动化测试

python接口自动化框架

python 接口自动化测试--框架整改

接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架