Test case framework optimization

I don't know if you remember. We shared it with you earlier Test case framework optimization (I) The third problem remains in the content process:

The third question: as for the field replacement, when there are many, many, thousands of interface use cases, replace them one by one, can you ensure that each field is replaced?

And it will be more troublesome to replace hundreds of thousands of interfaces one by one.

Now take the time to summarize the following and continue to share:

I encapsulate the process of extracting identifiers from} regular expressions and replacing them into a method:

We create a replacement py file:

——Problem solved: when writing test cases, all mark identifiers (#... #) involved in test cases can be replaced successfully

 

 

Note:

We just simply define a function here, and you can also define it as a class, because we have few functions now
You have more usage, like the requests method we encapsulated before. In fact, we only have def send_requests(self,method,api_url, data,token=None):
It is for external use, but there are some logical processing inside. We encapsulate it into classes and define some steps as private method processing,
So the reason is the same. If there are many situations for your project replacement in the future, you may need to expand here and there if you don't like it
This function is too long. You can also write it as a class like requests encapsulation. There is only one external method, and the others are private methods. You can directly
Call, the idea is the same.


import re
from common.my_data import Data
from common.mylogger import logger
from common.handle_phone import get_new_phone

def
replace_case_with_re(case_dict): """ :param case_dict: from excel There is a line of test data read out. In dictionary form. :return: Test data after replacement. The type is dictionary. """ # Step one, put excel An entire test case(excel One of the lines)Convert to string case_str = str(case_dict) # In the second step, regular expression extraction is used mark identifier to_be_replaced_marks_list = re.findall("#(\w+)#", case_str) # Step 3: traverse the identifier mark,If the identifier is a global variable Data Class, replace it with the property value mark if to_be_replaced_marks_list: logger.info("To replace mark The identifier has:{}".format(to_be_replaced_marks_list)) """ above if :if to_be_replaced_marks_list: Just will Data The identifier in the class is replaced. We It was also used when registering before"#phone#"It needs to be replaced. This is what we need to deal with before initiating the request, Therefore, we should deal with it all, and we should not miss it, because we Data It doesn't have this attribute, so replace it No, what should I do? Therefore, the data we use to replace may not be extracted from the response results, but may also be generated from scripts (such as phone),Or configuration files, which are not in the response results, but our framework Data It just encapsulates the data of the response result And we have only one framework phone This is a special case requiring special treatment. -resolvent: Write one if Judge, judge whether there is phone This identifier, if any, calls the script that generates the mobile phone number, and then replaces it If we have many business flows, we can also redefine a method to handle them """ # Judge whether there is phone This identifier, if any, calls the script that generates the mobile phone number, and then replaces it if "#phone#" in to_be_replaced_marks_list: new_phone = get_new_phone() logger.info("have#phone#Identifier, a new mobile phone number needs to be generated: {}".format(new_phone)) case_str = case_str.replace(f"#phone#", new_phone) # from Data Class to replace the identifier. for mark in to_be_replaced_marks_list: # If the global variable Data Class has mark This property name if hasattr(Data, mark): logger.info("Will identifier {} Replace with {}".format(mark, getattr(Data, mark))) # Use global variables Data Class mark Attribute value to replace the value in the test case#mark# case_str = case_str.replace(f"#{mark}#", getattr(Data, mark)) logger.info("The case data after replacement is: \n{}".format(case_str)) # Step 4: convert the whole test case after complete replacement back to the dictionary new_case_dict = eval(case_str) #The replaced data needs to be used in the next step, so we need to return it here return new_case_dict
If above: if to_ be_ replaced_ marks_ List: we just replaced the identifier in the Data class. We
        The "#phone #" needs to be replaced in the previous registration. This is also what we need to deal with before initiating the request,
        Therefore, we should do all the processing, and should not omit it, because we do not have this attribute in the Data, so we replace it
        No, what should I do? Therefore, the data we use to replace may not be extracted from the response results, but may also be generated from scripts
        (such as phone) or configuration files, which are not included in the response results, but our framework Data only encapsulates the Data of the response results
        Moreover, there is only one phone in our framework, which needs special treatment in special cases.
        ——Solution:
                Write an if judgment to judge whether there is a phone identifier. If so, call the script to generate the mobile phone number, and then replace it
                
        If we have many business flows, we can also redefine a method to handle them

 

 

Test case code example after encapsulating the replacement method:

import pytest
import os
import json

from common.myConf import MyConf
from common.my_path import conf_dir
from common.my_requests import MyRequests
from common.my_excel import MyExcel
from common.my_assert import MyAssert
from common.mylogger import logger
from common.my_path import testdata_dir
from common.my_data import Data
from common.my_extract import extract_data_from_response
from common.my_replace import replace_case_with_re

# Step 1: read the test data of the registered interface - It is a list. Each member in the list is the data of an interface use case.
excel_path = os.path.join(testdata_dir, "test case.xlsx")
print(excel_path)
me = MyExcel(excel_path, "Recharge interface")
cases = me.read_data()

# Step 2: traverse the test data, each group of data, and initiate one http Interface
# Instantiate request object
mq = MyRequests()
massert = MyAssert()


class TestRecharge:

    @pytest.mark.parametrize("case", cases)
    def test_recharge(self, case):
        """
        Here, we can directly remove the previous replacement method and reference the encapsulated replacement method
        :param case:
        :return:
        """
        # 1,Step 1: replace. If you need to replace it, you can replace it. If not, you don't need it
        case = replace_case_with_re(case)

        # 2,Replace the replaced request data(json Formatted string),Convert to a dictionary
        req_dict = json.loads(case["req_data"])

        # 3,Initiate the request and receive the response result
        if hasattr(Data, "token"):
            resp = mq.send_requests(case["method"], case["url"], req_dict, token=getattr(Data, "token"))
        else:
            resp = mq.send_requests(case["method"], case["url"], req_dict)
        logger.info(resp.json())

        # Result empty list
        assert_res = []

        # 5,Assert the data in the response result
        if case["assert_list"]:
            response_check_res = massert.assert_response_value(case["assert_list"], resp.json())
            assert_res.append(response_check_res)

        if False in assert_res:
            pass
        else:
            # 4,Extract data from response results,And set it as a global variable
            if case["extract"]:
                # Call extraction processing function
                extract_data_from_response(case["extract"], resp.json())

        # 6,Assertion database - sql Type of statement, result and actual comparison
        if case["assert_db"]:
            db_check_res = massert.assert_db(case["assert_db"])
            assert_res.append(db_check_res)

        # Final throw AsserttionError
        if False in assert_res:
            raise AssertionError

 

Added by serenade2 on Wed, 12 Jan 2022 13:51:10 +0200