[test and development practice] alfred + python + charles quickly debug the http interface

Before writing interface automation, you often need to carefully understand an interface, simulate the request and construct different request parameters to preliminarily verify the function of the interface. At present, in this process, it is found that it is very convenient and lightweight to directly use python requests to construct http requests, and the cost of custom verification of subsequent return parameters is also very low, Whether it is directly returned json, pb data or json P, it can be well supported. It is a good alternative to postman.

To this end, alfred has developed a tool to quickly generate python request code. The following is a detailed introduction

1. Basic structure of the project

 

1.1 the function requested by the debugging interface is placed in a file

pyPostman. The general structure of Py is as follows

import requests
import time

# The function code requested by the interface is defined here
def get_example():
    url = ''
    params = {

    }
    headers = {

    }
    resp = requests.get(url=url, params=params, headers=headers)
    print(resp.content)

def post_example():
    url = ''
    params = {

    }
    body = {
    }
    headers = {

    }
    resp = requests.post(url=url, params=params, data=body, headers=headers)
    print(resp.content)

# Execute function here
get_example()
post_example()

1.2 put some commonly used functions in another file

Provide some extended capabilities, requtils The general structure of Py is as follows

import json
import lvideo_api_pb2
import video_danmaku_pb2


# Refactoring and parsing json string to remove transfer
def getJsonDict(jsonData: dict):
    if type(jsonData) != dict:
        return
    for i in jsonData.keys():
        try:
            jsonData[i] = json.loads(jsonData[i])
            getJsonDict(jsonData[i])
        except TypeError:

            if (type(jsonData[i])) == dict:
                getJsonDict(jsonData[i])

            if (type(jsonData[i])) == list:
                for index in range(len(jsonData[i])):
                    try:
                        jsonData[i][index] = json.loads(jsonData[i][index])
                        getJsonDict(jsonData[i][index])
                    except TypeError:
                        if (type(jsonData[i][index])) == dict:
                            getJsonDict(jsonData[i][index])
                    except json.decoder.JSONDecodeError:
                        if (type(jsonData[i][index])) == dict:
                            getJsonDict(jsonData[i][index])

        except json.decoder.JSONDecodeError:

            if (type(jsonData[i])) == dict:
                getJsonDict(jsonData[i])

            if (type(jsonData[i])) == list:
                for index in range(len(jsonData[i])):
                    try:
                        jsonData[i][index] = json.loads(jsonData[i][index])
                        getJsonDict(jsonData[i][index])
                    except TypeError:
                        if (type(jsonData[i][index])) == dict:
                            getJsonDict(jsonData[i][index])
                    except json.decoder.JSONDecodeError:
                        if (type(jsonData[i][index])) == dict:
                            getJsonDict(jsonData[i][index])


# According to the interface data returned from the deserialization of pb file, you need to reference the py file compiled according to proto
def printIDL(psm, attr, serializeString):
    print('Deserialize parse data:')
    if (psm == 'xxx.lvideo.api'):
        try:
            streamResponse = getattr(lvideo_api_pb2, attr)()
            streamResponse.ParseFromString(serializeString)
            print(streamResponse)
            return streamResponse
        except Exception:
            print('Deserialization failed, continue output bytes')
            print(serializeString)
            return serializeString
    if (psm == 'xxx.danmaku.api'):
        try:
            streamResponse = getattr(video_danmaku_pb2, attr)()
            streamResponse.ParseFromString(serializeString)
            print(streamResponse)
            return streamResponse
        except Exception:
            print('Deserialization failed, continue output bytes')
            print(serializeString)
            return serializeString
    else:
        print('This is not supported at this time psm Deserialization of')
        print(serializeString)
        return serializeString

1.3 some examples of compiled pb files

The idlList folder can be directly import ed after being poured into the project directory. Note that when building in pycham, the folder needs to be set to source:

 

2. Use Alfrd tool to quickly generate python code and debug the interface

alfred tool download:

Link: https://pan.baidu.com/s/1av6RGfNwQ_4byfWSh9t0Qw Password: k5d7

2.1 demonstration of generating python code

https://www.bilibili.com/video/BV1vy4y147WB/

curlToReq tool demo

charles grabbing - copy curlrequest - call out alfred tool to quickly generate a complete executable code - copy it to pycharm for execution

2.2 structure analysis of generated code

According to the curl request string of the packet capture result, encapsulate the request url, request parameters, body and request header of a request into a json, and use the requests library to initiate get or post (only this request is supported temporarily) requests for debugging.

In many cases, request parameters are not always meaningful. You can find the necessary parameters by annotating some parameters. It is also very convenient to change some parameters (timestamp) into dynamic ones and generate them by python code. You can also quickly and easily verify the execution results. And some business scenarios involve multiple interface requests, and you can also quickly establish request links.

def test():
    getData = {
  "url": "https://slamdunk.sports.sina.cn/api",
  "params": {
    "p": "radar",
    "s": "leaders",
    "a": "players",
    "callback": "jQuery33108884994167071085_1616238380231",
    "page": "1",
    "limit": "15",
    "season_type": "reg",
    "item": "points",
    "item_type": "average",
    "_": "1616238380232"
  },
  "headers": {
    "Host": "slamdunk.sports.sina.cn",
    "Cookie": "ustat=__10.83.234.78_1616235699_0.16723900; genTime=1616235699; vt=4; Apache=1585052768675.2368.1616235701971; SINAGLOBAL=1585052768675.2368.1616235701971; ULV=1616235701976:1:1:1:1585052768675.2368.1616235701971:; recent_visited=[{\"t\":1616235701981,\"u\":\"https://nba.sina.cn/\"}]; statuid=__119.139.167.138_1616235713_0.93602600; statuidsrc=Mozilla/5.0+(Linux;+Android+10;+V1962A;+wv)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/62.0.3202.84+Mobile+Safari/537.36+VivoBrowser/9.1.10.1`119.139.167.138`http://slamdunk.sports.sina.cn/?vt=4`https://nba.sina.cn/`__119.139.167.138_1616235713_0.93602600; SLAMDUNK-SPORTS-SINA-COM-CN=; historyRecord={\"href\":\"https://slamdunk.sports.sina.cn/\",\"refer\":\"https://nba.sina.cn/\"}",
    "accept": "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01",
    "x-requested-with": "XMLHttpRequest",
    "user-agent": "Mozilla/5.0 (Linux; Android 10; V1962A; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36 VivoBrowser/9.1.10.1",
    "referer": "https://slamdunk.sports.sina.cn/?vt=4&key=tongji",
    "accept-language": "zh-CN,en-US;q=0.9"
  }
}
    resp = requests.get(url=getData['url'], params=getData['params'], headers=getData['headers'])
    print('Status code:', end='')
    print(resp.status_code)
    print('Response header:', end='')
    print(json.dumps(dict(resp.headers)))
    if 'json' in resp.headers['Content-Type']:
        print('response JSON character string:', end='')
        jsonResponse = json.loads(resp.content.decode())
        getJsonDict(jsonResponse)
        print(json.dumps(jsonResponse, ensure_ascii=False))
    if 'javascript' in resp.headers['Content-Type']:
        regex = ".*?\\(({.*?)\\);.*?"
        results = re.findall(regex, resp.text, re.S)
        print('response JSONP character string:', end='')
        jsonResponse = json.loads(results[0])
        getJsonDict(jsonResponse)
        print(json.dumps(jsonResponse, ensure_ascii=False))
        for i in jsonResponse['result']['data']['players']:
            print(i['last_name'] + 'score:' + str(i['points']))
    else:
        print('response bytes: ')
        print(resp.content)
        # printIDL('xxx.lvideo.api', 'ChannelResponse' , resp.content)
        # printIDL('xxx.lvideo.api', 'InfoResponse' , resp.content)
        # printIDL('xxx.danmaku.api', 'GetDanmakuResponse' , resp.content)
        # printIDL('xxx.danmaku.api', 'SendDanmakuResponse' , resp.content)
        # printIDL('xxx.danmaku.api', 'DanmakuReportResponse' , resp.content)

2.3 analysis of execution results

The automatically generated code will output three parts: status code, response header and response data by importing requtils mentioned above Py can also get the escaped json string, which can be copied to http://www.bejson.com/jsonviewernew/ View the detailed data structure, or respond to the data structure through code analysis or formulate validation rules.

Import the idlList folder and requtils mentioned above Py file, which can deserialize some return data to make it more readable, and formulate return data verification rules. Of course, you can also do more scene adaptation by yourself. That's the end of today's sharing

Finally, I would like to thank everyone who carefully reads my article. Watching the rise and attention of fans all the way, reciprocity is always necessary. Although it is not very valuable, you can take it directly if you can use it:

These materials should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse also accompanies tens of thousands of test engineers through the most difficult journey. I hope it can also help you!

In my QQ technology exchange group (technology exchange and resource sharing, advertising do not disturb)

You can take it away yourself, group number: free information in 310357728 groups is the essence of the author's more than 10 year test career. And the great gods of the same industry exchange technology together

If it helps you a little, your "praise" is the biggest driving force for Xiaobian's creation. See you in the next article!

 

 

Keywords: software testing Testing

Added by razta on Tue, 21 Dec 2021 04:50:03 +0200