How to use Python3+requests+unittest to implement interface automation testing practice

1. Introduction to Requests

First, let’s take a look at the official introduction of Requests:

Requests is an elegant and simple HTTP library for Python, built for human beings.

Translated: Requests is an elegant and simple Python HTTP library written for humans. This introduction is very straightforward, let us first feel the power of Requests.

import requests
 
# send request
response = requests.get(url="http://www.baidu.com/s", params={'wd':'python'})
# Process the response
print(response.status_code)
 
#return
200

If this request is implemented using urllib, the code is as follows:

import urllib.parse
import urllib.request
 
url = "http://www.baidu.com/s"
params = urllib.parse.urlencode({'wd':'python'})
# send request
response = urllib.request.urlopen('?'.join([url, params]))
# Process the response
print(response.getcode())
 
#return
200

It can be seen from the senses that using urllib will be more complicated in terms of URLs, parameters, etc. This is just the tip of the iceberg. In actual use, Requests surpasses urllib in many aspects. Its reputation is not in vain, and you will feel it in the following study.

2. Introduction to unittest

Speaking of Python’s unit testing framework, the first thing that comes to mind for friends who have been exposed to Python must be unittest. Indeed, as Python’s standard library, it is excellent and widely used in various projects. But you know what? In fact, among many Python projects, there are far more mainstream unit testing frameworks than this one.

This series of articles will introduce you to the currently popular Python unit testing frameworks, talk about their functions and features, and compare their similarities and differences, so that you can weigh the pros and cons and choose the best one when facing different scenarios and needs. Unit testing framework.

三、Python3 + requests + unittest

First of all, we can think about the process of interface testing

Second, choose the right framework

After the process was clear, we needed to choose a suitable framework, so we chose the Python3 + requests + unittest framework

The Requests module sends http network requests. The request types mainly include post, get, PUT, DELETE, and HEAD.

python + unittest unit test framework composition, and test report generation (HTMLTestRunner)

The detailed explanation of the framework will not be described here. Please refer to requests.

unittest reference click to view

Based on the above, let’s build our framework step by step. In this process, we need to separate business and data so that we can be flexible and achieve the purpose of writing the framework. Next, let’s divide the structure.

Our structure is like this

data: stores data documents used for automated testing

log: stores the generated log files

base: stores public methods

report: stores the generated automated test report

testcase: stores test scripts

Next, the development of public methods

Now that the overall structure has been divided, it’s time to fill in the entire framework step by step. Let’s first take a look at the public classes or functions in the Base file. This is mainly used for subsequent calls to test cases. All public and immutable data are It can be placed here and is easy to maintain.

The configuration document is as follows

[DATABASE]
data_address = ./data/
report_address = ./report/
 
[HTTP]
base_url = http://xxx.xx
 

Want to know how to get or write the corresponding data from the configuration file? Then keep reading

import os
import configparser
 
# Get the current py file address
proDir = os.path.split(os.path.realpath(__file__))[0]
# Combine config file address
configPath = os.path.join(proDir,"config.ini")
 
class ReadConfig:
    def __init__(self):
        #Get the configuration file under the current path
        self.cf = configparser.ConfigParser()
        self.cf.read(configPath)
 
    def get_config(self,field,key):
        #Get the key value in the configuration file
        result = self.cf.get(field,key)
        return result
 
    def set_config(self,field,key,value):
        #Write configuration information to the configuration file
        fb = open(configPath,'w')
        self.cf.set(field,key,value)
        self.cf.write(fb)
 

Then the question comes again, where to put our test data? How to get the value? How to write? How to save? . . .

Don’t worry, keep reading

Test data should be placed in excel or database first. Here is a brief introduction using excel as an example.

Two libraries for table operations are needed here. The xlrd data-driven reading works on excel documents, but xlrd cannot write data, so xlutils data-driven reading and writing are introduced.

The installation method can be installed using pip3 install xlrd and pip3 install xlutils.

import xlrd
import xlutils.copy
from Base.readConfig import ReadConfig
import time
 
class ReadExcel:
 
    def __init__(self,section,field,sheet):
        # Open the worksheet and navigate to sheet
        data_address = ReadConfig().get_config(section,field)
        workbook = xlrd.open_workbook(data_address)
        self.table = workbook.sheets()[sheet]
 
 
    def get_rows(self):
        # Get the number of excel rows
        rows = self.table.nrows
        return rows
 
    def get_cell(self,row,col):
        # Get cell data
        cell_data = self.table.cell(row,col).value
        return cell_data
 
    def get_col(self,col):
        # Get the entire column of data
        col_data = self.table.col_value(col)
        return col_data
 
classWriteExcel:
    def __init__(self,section,field,sheet):
        # Open worksheet
        self.address = ReadConfig().get_config(section,field)
        self.workbook = xlrd.open_workbook(self.address)
        self.wf = xlutils.copy.copy(self.workbook)
        self.ws = self.wf.get_sheet(sheet)
 
    def set_cell(self,row,col,value):
        #Set cell data
        self.ws.write(row,col,value)
 
    def save_excel(self,filename,format):
        #Get the current time
        self.time = time.strftime("%Y%m%d%H%M%S", time.localtime())
        #The file name and format of the generated file
        self.report = filename + '_' + self.time + format
        #save document
        self.wf.save(self.report)

Then, test the editing of the script

Everything is ready. Let’s use a simple and complete code to demonstrate the calling of public functions, the use of the framework and the generation of reports.

import unittest
import requests
from Base.readConfig import ReadConfig
from Base.readExcel import ReadExcel
from Base.readExcel import WriteExcel
#instantiation
readexcel = ReadExcel('DATABASE','data_address',0)
writeexcel = WriteExcel('DATABASE','data_address',0)
 
class testcase(unittest.TestCase):
    #initialization
    def setUp(self):
        #Get url
        self.base_url = ReadConfig().get_config('HTTP', 'base_url')
        self.url = self.base_url + readexcel.get_cell(1,1)
        #Get request headers
        self.headers = readexcel.get_cell(1,4)
 
    def test_case(self):
        nok = 0
        ner = 0
        # Loop through the test data in excel, verify the results, and generate a test report in excel form
        for i in range(3,readexcel.get_rows()):
            #Send a network request and get the response value
            response = requests.post(self.url, headers=self.headers, data=readexcel.get_cell(i,4).encode('utf-8'))
            actualresult = response.json()
            #Get the expected results in excel
            expectresult = eval(readexcel.get_cell(i,6))
            # Get the data to be verified
            key = eval(readexcel.get_cell(i, 5))
            keylen = len(key)
            j = 0
            for k in range(keylen):
                aresult = 'actualresult' + key[k]
                eresult = 'expectresult' + key[k]
                if eval(aresult) == eval(eresult):
                    #The expected results are consistent with the actual results
                    j=j+1
            if j == keylen:
                #Test data execution passed
                nok = nok + 1
                writeexcel.set_cell(i, 8, 'SUCCESS')
            else:
                # Test data execution fails and the actual results are written to excel
                ner = ner + 1
                writeexcel.set_cell(i, 8, 'FAILURE')
                writeexcel.set_cell(i, 7, str(actualresult))
                print('th', i + 1, 'The execution of the row test case failed: the expected result is', expectresult, 'The actual result is', actualresult)
            # Save test report
            writeexcel.save_excel('testreport', '.xls')
            print('Total number of test data', nok, 'Execution of test cases passed', ner, 'Execution of test cases failed')
 
    #Release resources
    def tearDown(self):
        pass
 
if __name__ == '__main__':
    #Construct test collection
    suite = unittest.TestSuite()
    suite.addTest(testcase('test_case'))
    #Create html file
    filename = ReadConfig().get_config('DATABASE', 'report_address') + 'testreport.html'
    fb = open(filename,"wb")
    #Execute tests and generate html test reports
    runner = HTMLTestRunner.HTMLTestRunner(stream = fb, description = 'Description information for the interface', title = 'Automated test report of so-and-so')
    runner.run(suite)
    #Close file
    fb.close()
 

Finally, the generated html report

Thank you to everyone who read my article carefully. Reciprocity is always necessary. Although it is not a very valuable thing, if you can use it, you can take it directly:

This information should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse has also accompanied tens of thousands of test engineers through the most difficult journey. I hope it can also help you!Yes Friends who need it can click on the small card below to get it

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 388,297 people are learning the system