干货 | 通用 api 封装实战,带你深入理解 PO

简介: 干货 | 通用 api 封装实战,带你深入理解 PO

image
image
1080×434 66.5 KB
在普通的接口自动化测试中,如果接口的参数,比如 url,headers等传参改变,或者测试用例的逻辑、断言改变,那么整个测试代码都需要改变。apiobject设计模式借鉴了pageobject的设计模式,可以实现一个优雅、强大的接口测试框架。

理念

apiobject设计模式可以简单分为6个模块,分别是API对象、接口测试框架、配置模块、数据封装、Utils、测试用例。

接口测试框架:base_api,完成对api的驱动
API对象:继承base_api后,完成对接口的封装
配置模块:完成配置文件的读取
数据封装:数据构造与测试用例的数据封装
Utils:其他功能封装,改进原生框架不足
测试用例:调用Page/API对象实现业务并断言
枯燥的讲述概念可能难以理解,后面的章节都会围绕这些模块进行理论的拆解和实例的演示。

api 模式应用

在这里将会结合企业微信的部门管理,获取部门列表接口作为一个接口测试用例,从没有封装到使用apiobject设计模式进行封装改造。将实战与理论结合,更深入理解apiobject设计模式。

环境准备
企业微信服务端API:接口文档 - 企业微信开发者中心

import requests

class TestDemo:

def test_get_token(self):

    r = requests.get(url="https://qyapi.weixin.qq.com/cgi-bin/gettoken",

        params={"corpid": "ww93348658d7c66ef4", "corpsecret": "T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIw"})

    return r.json()["access_token"]

def test_department_list(self):

    r = requests.get(url="https://qyapi.weixin.qq.com/cgi-bin/department/list",

        params={"access_token": self.test_get_token(), "id": 1})

    assert r.json()["errcode"] == 0

    return print(r.json())

思路
api
base_api.py是用来封装所有api的通用方法,比如打印log、对断言工具做二次封装等,不牵涉和业务相关的操作
wework.py继承base_api并实现基本业务,之后所有的具体的业务资源继承自wework,比如token的获取等;
department继承自wework,用来实现对应模块具体的业务逻辑,比如发送请求,请求内有什么参数等等。
testcases文件夹内统一存放所有的测试用例,调用API对象实现业务并断言
utils文件夹内存放对其他功能封装,改进原生框架不足
data文件夹数据构造与测试用例的数据封装此外,还有配置模块与数据封装会在后面的章节进行具体的介绍
image
image
1080×661 48.8 KB
实战案例

utils.py,在此文件中封装一个jsonpath方法。

import json

from jsonpath import jsonpath

class Utils:

@classmethod

def jsonpath(cls, json_object, expr):

    return jsonpath(json_object, expr)

base_api.py,在此文件中调用utils中的jsonpath方法。

from test_wework.utils.Utils import Utils

class BaseApi:

json_data = None

def jsonpath(self, expr):

    return Utils.jsonpath(self.json_data, expr)

wework.py,继承类BaseApi,实现token的获取。将在后面“通用api封装”章节中详细讲述函数内部的设计。

class WeWork(BaseApi):

corpid = "ww93348658d7c66ef4"

contact_secret = "T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIw"

token = dict()

token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"

@classmethod

def get_token(cls, secret=contact_secret):

    # 避免重复请求,提高速度

    if secret not in cls.token.keys():

        r = cls.get_access_token(secret)

        cls.token[secret] = r["access_token"]

    return cls.token[secret]

@classmethod

def get_access_token(cls, secret):

    r = requests.get(cls.token_url, params={"corpid": cls.corpid, "corpsecret": secret})

    return r.json()

department.py,继承类WeWork,发起一个get请求,获取department的list。

class Department(BaseApi):

list_url = "https://qyapi.weixin.qq.com/cgi-bin/department/list"

def list(self, id):

    self.json_data = requests.get(self.list_url, params={"access_token": WeWork.get_contact_token(), "id": id}).json()

    return self.json_data

test_department.py,断言返回值中的第一个name是否为“WestWayyt”。

class TestDepartment:

department = Department()

def test_department_list(self):

    r = self.department.list(1)

    assert self.department.jsonpath(expr="$..name")[0] == "WestWayyt"

通用 api 封装实战

在apiobject设计模式中,需要一个“base_api”作为其他api步骤的父类,把通用功能放在这个父类中,供其他的api直接继承调用。这样做的优点在于,减少重复代码,提高代码的复用性。

上文在演示使用api-object设计模式对脚本进行改造时提到了base_api。不过在上文,仅仅只是封装了一个utils中的一个简单方法。并没有完全体现出base_api的实际作用。

接下来会通过通用接口协议的定义与封装实战,实际体会一下base_api的巧妙之处。

base_api.py,在代码内,对request进行一层封装,当然在这里还看不出来具体的优势:

import requests

class BaseApi:

def request(self, method, url, **kwargs):

    self.json_data = requests.request(method=method, url=url, **kwargs)

    return self.json_data

wework.py,继承于类BaseApi,可以直接调用父类中的request方法(不需要导入requests库),从而发起一个get请求:

from test_interface.test_wework.api.base_api import BaseApi

class WeWork(BaseApi):

corpid = "ww93348658d7c66ef4"

contact_secret = "T0TFrXmGYel167lnkzEydsjl6bcDDeXVmkUnEYugKIw"

token = dict()

token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"

def get_access_token(self):

    r = self.request(method="get", url=self.token_url,

                     params={"corpid": self.corpid, "corpsecret": self.contact_secret})

    return r.json()

test_wework.py,继承于类WeWork,主要目的只是为了检查上面的get_access_token(self) 是否成功:

from test_interface.test_wework.api.wework import WeWork

class TestWeWork(WeWork):

def test_get_access_token(self):

    r = self.get_access_token()

    assert r["errcode"]==0

在上面的案例中,在base_api.py中对 requests 进行了多一层的封装,这样子,只要是属于BaseApi这个类的子类,都可以无需引用而直接调用 requests 库。从而发起各种各样的请求,实现了通用接口协议的定义与封装。

更多技术文章:https://qrcode.ceba.ceshiren.com/link?name=article&project_id=qrcode&from=bjhao&timestamp=1651808542

相关文章
|
29天前
|
编译器 API Android开发
Android经典实战之Kotlin Multiplatform 中,如何处理不同平台的 API 调用
本文介绍Kotlin Multiplatform (KMP) 中使用 `expect` 和 `actual` 关键字处理多平台API调用的方法。通过共通代码集定义预期API,各平台提供具体实现,编译器确保正确匹配,支持依赖注入、枚举类处理等,实现跨平台代码重用与原生性能。附带示例展示如何定义跨平台函数与类。
61 0
|
11天前
|
Rust API Go
API 网关 OpenID Connect 实战:单点登录(SSO)如此简单
单点登录(SSO)可解决用户在多系统间频繁登录的问题,OIDC 因其标准化、简单易用及安全性等优势成为实现 SSO 的优选方案,本文通过具体步骤示例对 Higress 中开源的 OIDC Wasm 插件进行了介绍,帮助用户零代码实现 SSO 单点登录。
|
1月前
|
JSON 数据管理 关系型数据库
【Dataphin V3.9】颠覆你的数据管理体验!API数据源接入与集成优化,如何让企业轻松驾驭海量异构数据,实现数据价值最大化?全面解析、实战案例、专业指导,带你解锁数据整合新技能!
【8月更文挑战第15天】随着大数据技术的发展,企业对数据处理的需求不断增长。Dataphin V3.9 版本提供更灵活的数据源接入和高效 API 集成能力,支持 MySQL、Oracle、Hive 等多种数据源,增强 RESTful 和 SOAP API 支持,简化外部数据服务集成。例如,可轻松从 RESTful API 获取销售数据并存储分析。此外,Dataphin V3.9 还提供数据同步工具和丰富的数据治理功能,确保数据质量和一致性,助力企业最大化数据价值。
93 1
|
17天前
|
Java 缓存 数据库连接
揭秘!Struts 2性能翻倍的秘诀:不可思议的优化技巧大公开
【8月更文挑战第31天】《Struts 2性能优化技巧》介绍了提升Struts 2 Web应用响应速度的关键策略,包括减少配置开销、优化Action处理、合理使用拦截器、精简标签库使用、改进数据访问方式、利用缓存机制以及浏览器与网络层面的优化。通过实施这些技巧,如懒加载配置、异步请求处理、高效数据库连接管理和启用GZIP压缩等,可显著提高应用性能,为用户提供更快的体验。性能优化需根据实际场景持续调整。
41 0
|
17天前
|
开发者
告别繁琐代码,JSF标签库带你走进高效开发的新时代!
【8月更文挑战第31天】JSF(JavaServer Faces)标准标签库为页面开发提供了大量组件标签,如`<h:inputText>`、`<h:dataTable>`等,简化代码、提升效率并确保稳定性。本文通过示例展示如何使用这些标签实现常见功能,如创建登录表单和展示数据列表,帮助开发者更高效地进行Web应用开发。
27 0
|
17天前
|
前端开发 API 开发者
【React状态管理新思路】Context API入门:从零开始摆脱props钻孔的优雅之道,全面解析与实战案例分享!
【8月更文挑战第31天】React 的 Context API 有效解决了多级组件间状态传递的 "props 钻孔" 问题,使代码更简洁、易维护。本文通过电子商务网站登录状态管理案例,详细介绍了 Context API 的使用方法,包括创建、提供及消费 Context,以及处理多个 Context 的场景,适合各水平开发者学习与应用,提高开发效率和代码质量。
21 0
|
17天前
|
JSON API 数据库
探索FastAPI:不仅仅是一个Python Web框架,更是助力开发者高效构建现代化RESTful API服务的神器——从环境搭建到CRUD应用实战全面解析
【8月更文挑战第31天】FastAPI 是一个基于 Python 3.6+ 类型提示标准的现代 Web 框架,以其高性能、易用性和现代化设计而备受青睐。本文通过示例介绍了 FastAPI 的优势及其在构建高效 Web 应用中的强大功能。首先,通过安装 FastAPI 和 Uvicorn 并创建简单的“Hello, World!”应用入门;接着展示了如何处理路径参数和查询参数,并利用类型提示进行数据验证和转换。
31 0
|
17天前
|
缓存 API 数据库
打造高性能后端API:从设计到部署的实战之旅
【8月更文挑战第31天】在数字化时代的浪潮中,后端API成为了连接用户、数据与服务的桥梁。本文将带领读者踏上一段从API设计、开发到部署的旅程,通过实际案例分析,揭示如何构建一个高性能的后端系统。我们将探讨现代后端架构的关键要素,包括RESTful API设计原则、数据库优化技巧、缓存策略、以及容器化部署的实践。文章旨在为开发者提供一套实用的方法论,帮助他们在面对复杂业务需求时,能够设计出既高效又可扩展的后端服务。
|
21天前
|
消息中间件 缓存 API
go-zero微服务实战系列(三、API定义和表结构设计)
go-zero微服务实战系列(三、API定义和表结构设计)