APIObject mode, principle and application (interface test framework actual combat)

APIObject patterns and principles

In ordinary interface automation testing, if the parameters of the interface, such as url, headers, etc., change, or the logic and assertion of the test case change, then the entire test code needs to be changed. The APIObject design pattern borrows from PageObject's design pattern and can implement an elegant and powerful interface testing framework.

idea

The APIObject design pattern can be simply divided into 6 modules, which are API object, interface test framework, configuration module, data encapsulation, Utils, and test cases.

  • Interface testing framework: base_api, complete the API drive

  • API object: After inheriting base_api, complete the encapsulation of the interface

  • Configuration module: complete the reading of the configuration file

  • Data encapsulation: data encapsulation of data structure and test cases

  • Utils: Other function encapsulation, insufficient improvement of native framework

  • Test case: call Page/API object to implement business and assert

The boring presentation of concepts may be difficult to understand, and the following chapters will focus on the theoretical disassembly and demonstration of examples of these 6 modules.

APIObject mode application

This chapter will combine the department management of the enterprise WeChat to obtain the department list interface as an interface test case, from no encapsulation to the use of APIObject design pattern for encapsulation transformation. Combine actual combat with theory to gain a deeper understanding of the APIObject design pattern.

Environmental preparation

Enterprise WeChat server API:

https://work.weixin.qq.com/api/doc/90000/90135/90664

Without any encapsulation and transformation of enterprise WeChat, get the department list interface test case:

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())

Ideas

File structure after transformation:

├── __init__.py
├── api
│   ├── __init__.py
│   ├── base_api.py
│   ├── department.py
│   └── wework.py
├── data
│   └── department_list.yml
├── testcases
│   ├── __init__.py
│   └── test_department_list.py
└── utils
    ├── __init__.py
    └── utils.py
  • API

    • base_api.py is a common method for encapsulating all APIs, such as printing Log, re-encapsulating the assertion tool, etc., without involving business-related operations;

    • wework.py inherits base_api and implements basic business. After that, all specific business resources are inherited from wework, such as token acquisition;

    • Department inherits from wework and is used to implement the specific business logic of the corresponding module, such as sending a request, what parameters are in the request, and so on.

  • All test cases are stored uniformly in the testcases folder, and API objects are called to implement business and assert;

  • The utils folder stores other function packages, which improves the lack of native framework;

  • Data folder data structure and data encapsulation of test cases;

In addition, there are configuration modules and data encapsulation that will be specifically introduced in the following chapters.

APIObject combat

utils.py, encapsulate a jsonpath method in this file.

import json

from jsonpath import jsonpath

class Utils:
    @classmethod
    def jsonpath(cls, json_object, expr):
        return jsonpath(json_object, expr)

base_api.py, call the jsonpathmethod in utils in this file .

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, inherited class BaseApi, to achieve token acquisition. The internal design of the function will be described in detail in the chapter "General API Encapsulation".

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, an inherited class WeWork, initiates a get request to get the list of department.

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, assert whether the first name in the return value is "WestWayyt".

class TestDepartment:
    department = Department()

    def test_department_list(self):
        r = self.department.list(1)
        assert self.department.jsonpath(expr="$..name")[0] == "WestWayyt"

Above, more advanced content of interface testing framework actual combat, we will share in follow-up articles. Pay attention to the " Programmer Two Black " official account to get more test and development dry goods content.

Guess you like

Origin blog.csdn.net/m0_52650621/article/details/112788636