1. Foreword
This article mainly explains the framework construction and modification of Python interface automated testing, automated test case design, dynamic parameterization form of use case design in interface testing, etc. This article will skip some of the framework construction content. Without further ado, let’s do it together. Take a look.
2. Practical exercises
2.1 Interface Introduction
We first use an interface as the starting point. This interface is the login interface, and the request method is POST. After logging in, you can perform various operations. The basic information is as follows:
2.2 Interface excel test case
According to the login interface document, design the test case:
2.3 framework common directory
Test cases belong to data, so we must read excel. We also have configuration files and a log system. These are all common content. We can first add the corresponding code module to common:
"""There is an easier way to read excel. This method is suitable for novices to learn and understand""" import openpyxl def read_excel(file_path, sheet_name): """Read data in excel""" workbook = openpyxl.load_workbook(file_path) sheet = workbook[sheet_name] values = list(sheet.values) workbook.close() title = values[0] rows = values[1:] new_rows = [dict(zip(title, rows)) for rows in rows] return new_rows """Log system""" import logging def get_logger(logging_name="Collector", logger_level="DEBUG", stream_level="DEBUG", file=None, file_level="INFO", fmt="%(asctime)s--%(levelname)s--%(filename)s--%(lineno)d--%(message)s"): """Get the logger collector""" logger = logging.getLogger(logging_name) logger.setLevel(logger_level) stream_handler = logging.StreamHandler() stream_handler.setLevel(stream_level) logger.addHandler(stream_handler) fmt_obj = logging.Formatter(fmt) stream_handler.setFormatter(fmt_obj) # Determine whether there is a file. If so, initialize file_handler. If there is no file, do not execute it. if file: file_handler = logging.FileHandler(file, encoding="utf-8") file_handler.setLevel("INFO") logger.addHandler(file_handler) file_handler.setFormatter(fmt_obj) return logger log = get_logger() """yaml reading results""" importyaml def read_yaml(file, encoding="utf-8"): with open(file, encoding="utf-8") as f: data = yaml.safe_load(f) return data
2.4 Test case design
Create a new test_login in the testcase directory to test login and implement excel reading and data driving. After obtaining the use case data, we first print and look at the data:
import unittest import requests from common.excel import read_excel from config import path_config from unittestreport import ddt, list_data # retrieve data data = read_excel(path_config.case_path, "login") @ddt class TestLogin(unittest.TestCase): @list_data(data) def test_login_success(self, case_data): print(case_data)
The complete code added is as follows:
import unittest import requests import json from common.excel import read_excel from config import path_config from unittestreport import ddt, list_data # retrieve data data = read_excel(path_config.case_path, "login") @ddt class TestLogin(unittest.TestCase): @list_data(data) def test_login_success(self, case_data): print(case_data """ 1. The first step is to get the response data 2. Obtain expected results 3. Comparison of expected results and actual results """ # Convert the json format string into a dictionary to avoid reading the string instead of the dictionary format when reading. json_data = json.loads(case_data["data"]) headers = json.loads(case_data["headers"]) expect = json.loads(case_data["expected"]) response = requests.request( method=case_data["method"], url=case_data["Api_Url"], json=json_data, headers=headers ) actual = response.json() self.assertEqual(actual["code"], expect["code"])
2.5 Use case design optimization
Create setting.py in the config directory, add the corresponding host domain name, and then splice the URLs:
# Domain name host = "http://IP:port" """Fragment code""" response = requests.request( method=case_data["method"], # Perform splicing and import settings before splicing. url=setting.host + case_data["Api_Url"], json=json_data, headers=headers )
In addition, we also need to perform assertion exception catching, and the complete code is modified again:
import logging import unittest import requests import json from common.excel import read_excel from config import path_config from unittestreport import ddt, list_data from config import setting # retrieve data data = read_excel(path_config.case_path, "login") @ddt class TestLogin(unittest.TestCase): @list_data(data) def test_login_success(self, case_data): print(case_data) """ 1. The first step is to get the response data 2. Obtain expected results 3. Comparison of expected results and actual results """ # Convert the json format string into a dictionary to avoid reading the string instead of the dictionary format when reading. json_data = json.loads(case_data["data"]) headers = json.loads(case_data["headers"]) expect = json.loads(case_data["expected"]) response = requests.request( method=case_data["method"], url=setting.host + case_data["Api_Url"], json=json_data, headers=headers ) actual = response.json() try: self.assertEqual(actual["code"], expect["code"]) log.info(f"Test case passed: {case_data}") except AssertionError as err: log.error(f"Test case failed: {case_data}, error message: {err}") # After the test case fails to capture, use raise to throw it raise err
3. Dynamic parameterization
For example, when we design a registration interface test case, we will encounter an obvious bottleneck. The mobile phone number has not been registered. The registration can be successfully completed when the automated test case is executed for the first time, but it cannot be registered on the second time. When you execute the test case for the second time, you will find that the mobile phone number already exists, so the test case will fail when executed for the second time. In the face of this situation, there are several solutions:
""" Solutions: 1. Every time you open excel manually and delete it, re-enter a new mobile phone number. 2. Query the mobile phone number in the database. If the mobile phone number already exists, delete the mobile phone number in the database. 3. The last digit of your existing mobile phone number + 1 4. Randomly generate a mobile phone number Idea analysis: 1. Although the first method can be solved, it requires manual replacement every time it is executed, which is inconvenient to maintain. 2. Although mobile phone numbers can be queried and deleted, real projects often do not easily perform database deletion operations, and a registered mobile phone number will have a table association, and in most cases the test does not have permission to delete it. 3. This is also a solution. We can add + 1 to the 11th digit every time. The disadvantage is that we will eventually encounter numbers that may conflict with other mobile phone numbers and the execution will fail. However, the efficiency is much higher than 1 and 1. 2 4. The final method is also dynamic parameterization. Mark the data that needs to be replaced. When the loop traverses the mark, use a randomly generated number to replace the mark so that it can pass smoothly when executing the use case. """
Dynamic parameterization is to solve this type of problem, so that the mobile phone number can be continuously and randomly changed, so that each execution will not cause the use case to fail due to the duplication of mobile phone numbers (using dynamic parameterization may still randomly change the registered number, but the probability is extremely low), and randomly generating a mobile phone number requires data forgery.
4. Data forgery
In the field of automated testing, data forgery is not something that undermines system security, but it is the hope that test case data can be automatically generated and the data conforms to certain rules, such as mobile phone numbers, email addresses, etc. Data forgery can be used in automated registration modules, or in login or other text input boxes to detect certain input rules.
Data forgery library in Python – faker library, install it through pip first:
import faker # Initialize the faker object and specify the generation rule area as China fk = faker.Faker(locale="zh_CN") result = fk.phone_number() print(f"Mobile phone number:{result}") # Randomly generate an address company = fk.company() print(f"Address:{company}") # Randomly generate a company address = fk.address() print(f"Company:{address}") # Randomly generate a city city = fk.city() print(f"city:{city}")
In addition to the standard forgery library that can provide forgery, we can also formulate a rule in the way we want:
def generate_new_phone(): phone = "1" + random.choice(["3", "5", "7", "8", "9"]) for i in range(9): num = random.randint(0, 9) phone + = str(num) return phone print(f"Functional mobile phone number:{generate_new_phone()}")
Simple encapsulation of forgery library functions. If you write data forgery code in a framework, you can put it in common and import it from common to generate some data:
import faker def generate_new_phone(): fk = faker.Faker(locale="zh_CN") result = fk.phone_number() return result # Modified fragment code (if you have any questions about the fragment code, please refer to the previous article): @ddt class TestLogin(unittest.TestCase): @list_data(data) def test_login_success(self, case_data): json_data = case_data["json"] if "#new_phone#" in json_data: new_phone = data_forgery.generate_new_phone() json_data = json_data.replace("#new_phone", new_phone)
Finally: The following is the supporting learning materials. For friends who do [software testing], it should be the most comprehensive and complete preparation warehouse. This warehouse has also accompanied me through the most difficult journey. I hope it can also help you. ! [100% free without any tricks]
Software testing interview applet
A software test question bank that has been used by millions of people! ! ! Who is who knows! ! ! The most comprehensive interview test mini program on the Internet, you can use your mobile phone to answer questions, take the subway, bus, and roll it up!
Covering these interview question sections:
1. Basic theory of software testing, 2. web, app, interface function testing, 3. network, 4. database, 5. linux
6. Web, app, interface automation, 7. Performance testing, 8. Programming basics, 9. HR interview questions, 10. Open test questions, 11. Security testing, 12. Computer basics