Interface test -- mock foundation + requests + unittest encapsulation -- actual operation

        It's all right here. I've talked about interface testing before. This chapter is mainly based on actual combat to let you know about mock, because the interface data seen in this chapter is generated by mock. Mock will be introduced in detail later.

        The mock in this article is a py file written by the blogger, so friends who want to fight can add the blogger micro: qing_an_an, the blogger also has an exchange group. You can comment into the group and take you to know different knowledge points every day.

catalogue

preface

Send request

Extract token

session

cookie

auth authentication

Interface encapsulation

preface

        The mock data in py is the main content, so you can find the blogger to get the file before learning. The file is provided free of charge!

        We will use the flash framework to simulate the writing interface. Let's go directly to the example and explain it in detail in the following chapters:

from flask import Flask, request

# Initialize the flash framework
# Different functions return different data, which can be located through routing
app = Flask(__name__)

@app.route("/app/query", methods=['GET'])
def queryInfo():
    return "hello world"

if __name__ == '__main__':
    app.run(port=8080)

        After running, access directly http://127.0.0.1:8080/app/query You can see the word hello world on the web page. / APP / query can be called routing. To access the method, we specify the GET method. route is called routing function, which is divided into static path and dynamic path. You can visit here to see the effect. The port number port can be changed by yourself. 778888 is OK.

        Let's start with an appetizer, simulate the request, and thank you for your support:

import requests

url = 'http://127.0.0.1:5000/api/qingan/demo'
res = requests.get(url)
print(res.text)

         I wrote some interface data in the file, so before learning, I can contact the blogger to get the source file and learn after running.

Send request

        Let's first use the tool to request this interface. Here I use the domestic light API post:

         If the above settings are data, you need to add the following head content in the header. We can see that the request can be successful here. Let's look at how the code is written:

import requests

url = 'http://127.0.0.1:5000/api/qingan/login'
data = {
    "username": "admin",
    "password": "123456",
}
head = {"Content-Type": 'application/json'}
res = requests.post(url, json=data, headers=head)
print(res.json())

         Here, because we have converted the json format, the header information can be successfully requested without adding. After the request is successful, we can see the token in the return information. We can directly proceed to the next step.

Extract token

        In the above example, we directly take the token. Extracting the token must be after the request and after the request is successful.

        Token is used to identify the identity of the interface caller, including the credentials. In short, with a token, you can log in free

        The token is usually placed in the header or body parameter of the request header

        A token is generally composed of signature + timestamp, so it can be one-time or valid within a certain time range

session

        We have other ways to extract token s, using session. Generally speaking, if you successfully log in to a website using session, the session object will save the information to be carried, such as cookie s and header s. If you use the session object again to access other pages of the website (view order information), these parameters will be carried by default.         

        Let's take a look at how the above example works:

import requests

url = 'http://127.0.0.1:5000/api/qingan/login'
data = {
    "username": "admin",
    "password": "123456",
}
head = {"Content-Type": 'application/json'}
se = requests.session()
res = se.post(url, json=data, headers=head)
print(res.json())

get_token = res.json()['token']
# Get the token through the seesion session. If you don't write it, the access will fail
se.headers.update({'token': get_token})
print(se.headers)
url2 = 'http://127.0.0.1:5000/api/qingan/userList'
# Through the session, you can not add a header, and the header information will be added automatically
rres = se.get(url2)
print(rres.text)

        We use the session object in the requests library to make requests. The session object can also send post, get and other requests. Next, we will introduce the auth attribute of the session object, and then look at it.

        In the code, we extracted the token and updated the header information. In order to see it more clearly, I added a print. After receiving the friend's request of the code, we will see that the token information is added to the header information. Thus, we can send the following user query interface to query.

        If the session object is not used, what about the normal operations:

import requests

url = 'http://127.0.0.1:5000/api/qingan/login'
data = {
    "username": "admin",
    "password": "123456",
}
head = {"Content-Type": 'application/json'}
res = requests.post(url, json=data, headers=head)
print(res.json())

get_token = res.json()['token']
head['token'] = get_token
url2 = 'http://127.0.0.1:5000/api/qingan/userList'
rres = requests.get(url2,headers=head)
print(rres.json())

         Both, from the code point of view, the following example seems to be a few lines less code. Hey, look at your personal needs and choose by yourself.

cookie

        There's no need to say more about cookie s. Go directly to the example. Let's give you the example web page first. It's only for learning. There are login account passwords on it. Malicious brushing is prohibited. Note: please contact the blogger to delete if the project infringes Login - Open Source mall | B2C mall | B2B2C mall | three-level distribution | free mall | multi-user mall | TPshop | thinkphp shop | TPshop free open source system | micro mall

import requests

url = 'http://www.testingedu.com.cn:8000/index.php?m=Home&c=User&a=do_login'
data = {
    "username":"13800138006",
    "password":"123456",
    "verify_code":"1111"
}
head = {"Content-Type": 'application/x-www-form-urlencoded'}
se = requests.session()
res = se.post(url,data=data,headers=head)
print(res.json())

url2 = 'http://www.testingedu.com.cn:8000/Home/Order/order_list.html'
rres = se.get(url2)
print(rres.text)

        Generally, if we want to skip cookies and log in directly, we need to obtain cookies, but we log in directly through the session object. As for obtaining content without skipping login through the session object, the blogger wrote an article: Teach you to log in using cookie s_ Qinghuan nothing else - CSDN blog You can make a reference. Relatively speaking, session is simpler.

        Like the above example, the session object will automatically carry this information. As long as you use the same variable to initiate a request, it can also be called a session request. After a successful response, use this variable again for the next interface request and it will be automatically added.

auth authentication

        There are also written examples of auth authentication in the file. Auth authentication has a certain relationship with encryption, so we will talk about encryption here. There are many ways to encrypt. If you encounter this on your own web page, it doesn't matter if you have enough time. Otherwise, give up. Decryption is too cumbersome.

        Let's take a look at this website first. If it's the same, it's limited to learning: New list

         Here you can see that the password is encrypted. Many web sites should be encrypted, but you don't know what to encrypt. However, this does not affect our access to it. After successful registration and access, it will be displayed here. Therefore, we directly copy the url:

         Enter postman and click Import to import:

         You can access it by importing it. I have not registered here. Here is also a way to access it:

        Let's take a look at our own interface. Let's use postman to see auth authentication:

         After the request, you can see that the request is successful. If you change the password, the request will not be available. Then look at the following code:

        Let's take a look at the encryption part first: the example here is base64

import base64

username = 'admin'
password = 'qingan123456'
res = base64.b64encode(bytes(username,encoding='utf-8')).decode('ascii')
res1 = base64.b64encode(bytes(password,encoding='utf-8')).decode('ascii')
print(res,res1)
# Result YWRtaW4= cWluZ2FuMTIzNDU2

        In this case, we can't request success, so we need to change:

import requests
import base64

username = 'admin'
password = 'qingan123456'
res2 = base64.b64encode(bytes(username,encoding='utf-8')+b":"+bytes(password,encoding='utf-8')).decode('ascii')

print(res2)
# YWRtaW46cWluZ2FuMTIzNDU2

        Let's start the request with encrypted code:

# -->>>Qing'an<<<---
import requests

url = "http://127.0.0.1:5000/api/qingan/auth"

payload={}
headers = {
  'Authorization': 'Basic YWRtaW46cWluZ2FuMTIzNDU2'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

# {
#   "code": 10200, 
#   "message": "Authorization success!"
# }

        If you want to encrypt from time to time, you can change the above encryption process to input encryption.

        Since auth authentication is used, can we quickly solve this problem through the session object in the requests library to simplify the process:

url = "http://127.0.0.1:5000/api/qingan/auth"
sess = requests.session()
sess.auth = ('admin','qingan123456')
res = sess.request("POST",url)
print(res.json())

        The result will not be posted. It is consistent with the above results. The answer is that the process can be simplified through the session object.

Upload file

        Project address: http://www.testingedu.com.cn:8000/index.php/home/Uploadify/imageUp/savepath/head_pic/pictitle/ban ner/dir/images.html

        Looking directly at a wave of code, the interface for uploading files is relatively simple:

import requests

url = 'http://www.testingedu.com.cn:8000/index.php/home/Uploadify/imageUp/savepath/head_pic/pictitle/ban ner/dir/images.html'
files = {
    'file':(
        'qing.jpg', # File name
        open(r'F:\qing.jpg','rb'), # File path
        'image/jpg' # file type
    )
}
data = {
    "name":"qing.jpg"
}
res = requests.post(url, data=data,files=files)
print(res.json())

        The response information is generally viewed in json format, but there are other cases where text is used, depending on the document. Otherwise, it depends on your own experience.

Interface encapsulation

        Encapsulation is also based on mock data, so please try to get the document and then refer to this article.

        Directly paste the code and analyze it a little bit:

# -->>>Qing'an<<<---
import requests

class HttpClientRequest():
    def __init__(self):
        # Create session
        self.session = requests.session()
        self.url_pre = 'http://127.0.0.1:5000/api/qingan/'

    def init_headers(self, head=None):
        self.head = {"Content-Type": 'application/json'}
        if head:
            self.session.headers.update(head)

    def SendRequest(self, method, url, **kwargs):
        self.url = self.url_pre + url
        # print(kwargs)  #{'json': {'username': 'admin', 'password': '123456'}}
        self.data = None
        if 'json' in kwargs:
            self.data = kwargs['json']  # {'username': 'admin', 'password': '123456'}
        self.res = self.session.request(method=method, url=self.url, json=self.data)
        self.response = self.res.json()

        # Extract the value in the response result -- token:
        if 't_token' in kwargs:  # {'json': {'username': 'admin', 'password': '123456'}, 't_token': 'token'}
            self.val = kwargs['t_token']  # 'token'
            self.get_token = self.response[self.val]

            # The token is appended to the request header
            # self.session.headers.update({self.val:self.get_token})
            self.init_headers({self.val: self.get_token})

        return self.response

        Here is a method class__ init__ The session object is used and a url address prefix is used by default. Because the mock data written is basically prefixed with this, it is written directly in the initialization. It doesn't matter here.

         init_ The default value of headers is none and null. If any value needs to be updated, it will be updated. Here, the distance is the token value to be retrieved. If so, update it for subsequent calls.

         SendRequest sends the request. First, splice the url. Given that the data is a null value, judge whether it is in json format. If so, extract the value and then initiate the request.

        Subsequently, we initiate a request for the subsequent interface smoothly, so we need to extract the token. After extracting the token, we need to update it to the header parameter. * kwargs can receive multiple values, so we need to judge t_ Whether the token has been passed. If it has been passed, it will receive the token with a variable, self.get_token is also one of our variables, which is used to receive the value corresponding to the extracted token. Then, there is our self   init_ Needless to say, headers are added to the header parameter for subsequent requests.

# -->>>Qing'an<<<---
import unittest
from httpapi import HttpClientRequest

class HuaceTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(self) -> None:
        self.request = HttpClientRequest()

    def test01(self):
        '''Successfully logged in to the interface'''
        data = {
            "username": "admin",
            "password": "123456"
        }
        self.res = self.request.SendRequest(method='post', url='login', json=data, t_token='token')
        print(self.res)

    def test02(self):
        '''User information query interface'''
        self.res = self.request.SendRequest(method='get', url='userList')
        print(self.res)

if __name__ == '__main__':
    unittest.main()

         I used unittest to write the use case file. The instantiation method is used. In fact, there is nothing to say here. It is to transmit data, then the other side receives the data transmitted here, makes a series of judgments, calls methods and extracts values. Finally, make a request. Get our ideal result.

        It is mainly the previous method, not here. Here, it is necessary to divide the primary and secondary relationships.

Tags: interface API testing

Posted on Fri, 03 Dec 2021 01:42:03 -0500 by jayrulez