This article appeared in:Walker AI

In the process of interface automation test, there is not only single interface test, but also scene test, which causes the problem of value passing between interfaces. The following describes how to handle interface value passing under pyTest framework.

Overall interface data can be divided into pre-processing and post-processing:

Pre-processing: some fixed value or fixed method call

Postprocessing: Requires body and response from previous requests

1. Obtain data

Pre-processing:

Preprocessing is marked with <> and [] (markers can be changed to suit your needs)

When the regular matching data contains either of these tags, the reading calls the method in methlib.py or config.py, which fixed value or method is called, according to the parameters written in the tag, and the data is replaced. Where <> is used to mark a fixed value, [] is used to mark a fixed method;

Post-processing:

Postprocessing is marked with &&, {}, ==, ## (markers can be changed to suit your needs)

When the regular matching data contains these tags, the data in requestmsg. TXT is read, which row of data is read, and the data is judged according to the data in the associated column, and the data is replaced. Where && is used to mark the body of the previous step, {} is used to mark the response of the previous step, == is used to mark the body of the previous step, ## is used to mark the response of the previous step;

Note: ① The use case transmission parameters in excel are written in the form of dictionary as needed. ② Add the associated column to the table data, which is used to determine the parameters or responses of the requests read. ③ For some interfaces that need to be encrypted, add an encryption column to the table data to determine whether the parameters of the interface are encrypted.

2. Test process

Pre-processing:

The excel table data read is the data of a module. After processing by PyTest, the data (list) of multiple interfaces in the module will be transmitted to a single interface. It is the data obtained without any request, so it is put in a separate data processing. The following is a pre-processing only process;

Post-processing:

The data needs to be obtained from the request or response of the previous interfaces, so it must be placed before the request. And every time you send an interface request, you need to write the body and response of the request in request. TXT for the use of the following interfaces. Here is the post-processing only process;

The following is the interface test process through pre – and post-processing;

3. Code implementation

Implementation of preprocessing: Preprocessing is independent of the parameters and responses of other requests, so the entire module can be processed.

def param_method(dic_param) :
	""" Fixed value, take method (not body and response) :param dic_param: must be a dictionary (argument in data) :return: """
	temp_mobile_ = []
	temp_email_ = []
	temp_pid_ = []
	for j in dic_param.keys():
		value__ = dic_param[j]
		_ = re.findall(r'\<(.*?) > '.str(value__)) # fixed value
		__ = re.findall(r'\[(.*?)] '.str(value__)) The technique of #
		if_ :# Determine if there is a fixed apK passthrough
			dic_param[j] = param[f'{_ [0]}']
		if__ :if j == 'mobile' or 'phone' or 'phoneNum':
				dic_param[j] = mobile()
				temp_mobile_.append(dic_param[j])
			if j == 'email':
				dic_param[j] = email()
				temp_email_.append(dic_param[j])
			if j == 'pid':
				dic_param[j] = pid()
				temp_pid_.append(dic_param[j])
			if j == 'app_order_id':
				dic_param[j] = get_random_str(30)
	return dic_param
Copy the code

Implementation of postprocessing: Postprocessing is related to the parameters and responses of other requests, so it must be processed before each request. The method of postprocessing is shown below. Due to the length of the code, only part of the postprocessing code is shown.

def prev_body_res(dic_param, relevance=None) :
    Dic_param: must be in the dictionary format :return: ""
    request_file = r'./requestsmsg.txt'
    for j in dic_param.keys():
        value__ = dic_param[j]
        ___ = re.findall(r'\&(.*?) & '.str(value__))  # Take the previous body
        ____ = re.findall(r'\{(.*?) } '.str(value__))  # Take response from above
        _____ = re.findall(r'\#(.*?) # '.str(value__))  # Take response from previous steps
        ______ = re.findall(r'\=(.*?) = '.str(value__))  # Take the body of the previous step
        if ___:
            request_res = readtxt(request_file)
            request_body = request_res[1]
            key = ___[0]
            res_data = request_body[f'{key}']
            dic_param[j] = str(res_data)
        if ____:
            request_response = readtxt(request_file)
            request_response = request_response[0]
            key = ____[0]
            res_data = request_response['data']
            if res_data:
                if isinstance(res_data, list):
                    temp_value = get_dict_value(request_response['data'] [0], key)
                    dic_param[j] = temp_value[0]
                    temp_value.clear()
                else:
                    temp_value = request_response['data'] [f'{key}']
                    dic_param[j] = str(temp_value)
Copy the code

Specific applications of post-processing: Since post-processing requires the previous request to complete before the desired data is obtained, the specific post-processing is placed before each request is processed. The application of the specific request is shown below.

    else:  # the value
        line_data = prev_body_res(line_data, relevance_no)
        if i['encryption'] = ='0':  # is not encrypted
            if header['Content-Type'] = ='application/json':
                response = requests.request(f'{request_type}', url=url, headers=header, data=json.dumps(line_data))
                write_request(response.json(), no, line_data)
                logger.info(f'response:{response.json()},no:{no},body:{line_data}')
Copy the code

Parametrize Module value handling based on PyTest: Take the mailbox login module in data preparation for example: This decorator will parametrize data across the module to the method defined below.

    @allure.story('Email login')
    @pytest.mark.qa
    @pytest.mark.formal
    @pytest.mark.parametrize('excel_data', change_data(module_data('Email login'), len(module_data('Email login'))))
    def test_login_email(self, excel_data) :
        response = decide_value_relevance(excel_data)
        judge_result(response, 'Email login')
        title = excel_data['title']
        allure.dynamic.title(F 'Email login:{title}')
Copy the code

4. To summarize

Based on PyTest, we can assemble the scenarios we need to test in the form of modules, and then pass values to build a number of different normal and abnormal scenarios to increase the relevance. Using tables to build data also adds flexibility to build scripts; Later there are many places to optimize, hope to discuss with you.


PS: more dry technology, pay attention to the public, | xingzhe_ai 】, and walker to discuss together!