Python+Requests realizes interface automation

Generally speaking, there are two ways of understanding automation.

First, there is no need to write code and it is completely implemented by tools. Tools of this method are generally developed by the company itself and are convenient for black box testers to use. The characteristics of this kind of tool are low learning cost and easy to use, but it is not very versatile. That is, if you change a company, you may not be able to use the previous tool.

Second, you need to write your own code and write code tests under someone else’s framework, or you need to build your own automated testing framework. This method has high code requirements for testers and high learning costs, but it is very versatile and can be used by any company.
In view of the above introduction, this article will of course introduce the second method.

Interface automated testing, our purpose is to use python to conduct interface testing and complete the output test report. The things we need to use are as follows: python3, unittest, requests.

1. Interface project

The project we use is a press conference sign-in system. There are a total of 5 interfaces. Although not many, they are enough to learn and use.

The interface documentation is as follows:





2. Interface use cases

Software testing requires writing test cases, whether you are doing performance, automation or any other testing work.

When writing interface test cases for real work, many scenarios may be considered, such as the function of the interface (normal scenario), the boundary equivalence of the interface, the abnormal scenario of the interface, the combination of interface parameters, the performance of the interface, etc. This article adopts output method analysis and designs test cases based on different output parameters. The detailed use case reference is as follows: (The use case is too small to see clearly, you can view the original picture and then enlarge it)

3. Code stage

3.1 Framework design

We use the unittest framework. The case directory stores all test cases, the lib directory stores some of the codes encapsulated by itself, the results directory stores test results and test logs, and runner.py is the main program.


3.2 Main program runner.py

This main program is similar to the previous “Selenium Unittest Practice” article and will not be introduced in detail. The difference is that it uses a logging module. I don’t know if you feel it. When testing the interface, I want to see the complete request and response in order to analyze and locate the problem.

import unittest
import time
import os
import logging
from HTMLTestRunner import HTMLTestRunner

#Get the root directory of the project
test_dir = os.path.join(os.getcwd())

# Automatically search all cases in the project root directory and construct a test set; return the TestSuite object
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

# Instantiate the TextTestRunner class
# runner = unittest.TextTestRunner(verbosity=2)

now = time.strftime('%Y-%m-%d %H_%M_%S') # Get the current date
result = test_dir + '\result\' + now + '_result.html' # Full path to the test report
log = test_dir + '\result\' + now + '_log.txt' #Full path of log

logging.basicConfig(filename=log,level=logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s') #filename log file path level Log level format format

fp = open(result, 'wb') # Write in wb mode
runner = HTMLTestRunner(stream=fp, title='Test report', description='aguest_master project use case execution', verbosity=2) #Construct runner

# Use the run() method to run the test suite (that is, run all test cases in the test suite)
runner.run(discover)

3.3 Test cases and lib libraries

1) Since there are only 5 interfaces in total, it is designed as 5 code files, namely: test_add_event,py, test_add_guest.py, test_get_event_list.py, test_get_guest_list.py, test_user_sign.py.


2) We use python’s requests test interface. This library is famous, and the official website is also in Chinese.

Official website: http://docs.python-requests.org/zh_CN/latest/

3) Each code file is an interface, and the URL address of the interface is fixed, so it is designed as a class attribute to facilitate the use of subsequent test cases.


4) Each test case clearly states the code logic to facilitate future debugging.
5) If you encounter something that is frequently called, such as getting the latest conference ID and getting the body data of the added conference, they are all packaged into a library.
6) Finally, determine whether the assertion is successful based on the status code of the parameter.
7) Use http://logging.info to record the log status of each test case


Add conference interface code file: test_add_event.py

import requests
import unittest
import logging
import addEventDataTemplate
import getNewID
from urllib import parse #Use requests to send post requests. The Chinese characters in the body will be URL encoded, that is, in the form of %xx. If you want to see the original body, you need to use parse.unquote to enter the url decoding
class Test_addEvent(unittest.TestCase):
    '''Add conference interface'''
    @classmethod
    def setUpClass(cls):
        cls.url="http://127.0.0.1:8000/api/add_event/"
    @classmethod
    def tearDownClass(cls):
        pass
    def setUp(self):
        pass
    def tearDown(self):
        pass
    def test_00(self): #Code logic:: Get the latest conference ID, set input parameters, leave eid blank, and send post request
        '''Add press conference-eid is empty'''
        id=getNewID.getNewID() #Get the latest conference ID
        data=addEventDataTemplate.getEventData(id) #Get the data template for adding a conference
        data['eid']='' #eid is empty, that is, the parameter is wrong
        r=requests.post(self.url,data=data)
        status=r.json()['status']
        self.assertEqual(10021,status)
        logging.info(f"case: add press conference, eid is empty\\
Request address: {r.url}\tRequest method: {r.request.method}\\
Request header: {r.request .headers}\\
Request body: {parse.unquote(r.request.body)}\\
Response header: {r.headers}\\
Response body: {r.text}\\
")

    def test_01(self): #Code logic:: Get the latest conference ID, set input parameters, and send post request
        '''Add press conference-success'''
        id = getNewID.getNewID() # Get the latest conference ID
        data = addEventDataTemplate.getEventData(id)#Get the data template for adding the latest conference
        r=requests.post(self.url,data=data)
        status=r.json()['status']
        self.assertEqual(10000,status)
        logging.info(f"case: Add conference, successful\\
Request address: {r.url}\tRequest method: {r.request.method}\\
Request headers: {r.request.headers }\\
Request body: {parse.unquote(r.request.body)}\\
Response header: {r.headers}\\
Response body: {r.text}\\
")

    def test_02(self): #Code logic:: Get the latest conference ID, ID-1 is the existing ID of the conference (the conference ID is increased by 1 incrementally)
        '''Add conference-the conference ID already exists'''
        id = getNewID.getNewID() # Get the latest conference ID
        data=addEventDataTemplate.getEventData(id)#Get the data template for adding the latest conference
        data['eid']=data['eid']-1 #The latest template ID minus one is a duplicate ID
        r=requests.post(self.url,data=data)
        status = r.json()['status']
        self.assertEqual(10022, status)
        logging.info(f"case: Add conference, conference ID already exists\\
Request address: {r.url}\tRequest method: {r.request.method}\\
Request header: {r .request.headers}\\
Request body: {parse.unquote(r.request.body)}\\
Response header: {r.headers}\\
Response body: {r.text}\\
" )
    def test_03(self): #Code logic:: First add a new conference, then get the latest conference ID, and set the name of the input parameter to be repeated.
        '''Add press conference - the press conference title already exists'''
        #New press conference
        id = getNewID.getNewID() # Get the latest conference ID
        r=requests.post(self.url,data=addEventDataTemplate.getEventData(id)) #First add a press conference

        id = getNewID.getNewID() # Get the latest conference ID
        data = addEventDataTemplate.getEventData(id)#Get the data template for adding the latest conference
        data['name']=f'Conference test title{id}' #The latest template ID is reduced by one, and the title is repeated
        r=requests.post(self.url,data=data)
        status = r.json()['status']
        self.assertEqual(10023,status)
        logging.info(f"case: Add a conference, the conference title already exists\\
Request address: {r.url}\tRequest method: {r.request.method}\\
Request header: {r .request.headers}\\
Request body: {parse.unquote(r.request.body)}\\
Response header: {r.headers}\\
Response body: {r.text}\\
" )
    def test_04(self): #Code logic:: Get the latest conference ID, set the input parameters, start time: change to -, and then submit the request
        '''Add press conference - press conference time error'''
        id = getNewID.getNewID() # Get the latest conference ID
        data = addEventDataTemplate.getEventData(id)#Get the data template for adding the latest conference
        data['start_time']=data['start_time'].replace(':','-') #Time: changed to -, which is a time error
        r = requests.post(self.url, data=data)
        status = r.json()['status']
        self.assertEqual(10024,status)
        logging.info(f"case: Add press conference, press conference time is wrong\\
Request address: {r.url}\tRequest method: {r.request.method}\\
Request header: {r. request.headers}\\
Request body: {parse.unquote(r.request.body)}\\
Response header: {r.headers}\\
Response body: {r.text}\\
")
if __name__ == '__main__':
    unittest.main(verbosity=2)
lib library getNewID.py:

def getNewID():
    '''Get the latest (largest) conference number id'''
    import sqlite3
    con=sqlite3.connect(r'D:\backup\guest2-master\db.sqlite3')
    cur=con.cursor()
    cur.execute("select max(id) from sign_event")
    new_id=cur.fetchone()
    new_id=new_id[0]
    cur.close()
    con.close()
    return new_id
lib library addEventDataTemplate.py:

import datetime
def getEventData(id):
    '''Add conference body template'''
    startTime=(datetime.datetime.now() + datetime.timedelta(days=30)).strftime("%Y-%m-%d %H:%M:00") #Get the current time and go to The next 30 days will be the release date

    data={
          'eid':id + 1,
          'name':f"Conference test title {id + 1}", #Add 1 to the current conference number
          'limit':100, #Default value
          'status':1, #Default value
          'address':'Xinjiekou Golden Eagle', #Default value
          'start_time':startTime #%Format Y-%m-%d %H:%M:00
        }
    return data

Due to space reasons, other codes are omitted.

Final test results:


The log results are as follows:


Summary: In the process of writing code, the code logic of each test case is very important. No matter what the logic is, it must be ensured that each test case code can run independently without coupling. Also when testing the interface, you often deal with the database, such as obtaining data, judging test results, etc.

Finally: The complete software testing video learning tutorial below has been compiled and uploaded. Friends can get it for free if needed [Guaranteed 100% Free]

The above complete version of the learning materials has been uploaded to CSDN official. If necessary, you can scan the CSDN official certification QR code below on WeChat to get it

[[CSDN gift package: “python & full set of learning materials” free sharing]](Safety Link, feel free to click)





1. Python learning outline

The technical points in all directions of Python are organized to form a summary of knowledge points in various fields. Its usefulness is that you can find corresponding learning resources according to the above knowledge points to ensure that you learn more comprehensively.

2. Essential development tools for Python

3. Introductory learning video

4. Practical cases

Optical theory is useless. You must learn to follow along and practice it in order to apply what you have learned to practice. At this time, you can learn from some practical cases.

5. Python side job part-time and full-time routes

The above-mentioned complete version of the complete set of Python learning materials has been uploaded to the CSDN official. If necessary, you can scan the CSDN official certification QR code below on WeChat to get it

[[CSDN gift package: “python installation package & full set of learning materials” free sharing]](Safe link, click with confidence)