¿Cómo completar el marco de automatización? Automatización de la interfaz de Python: combate basado en datos, un artículo es suficiente...


prefacio

En nuestro escenario de prueba, una interfaz de inicio de sesión puede tener una docena o docenas de casos de prueba. Si cada conjunto de datos se escribe con un método, habrá más código duplicado, no solo la eficiencia de ejecución no es alta, sino que tampoco lo es. facil de mantener.

A continuación, optimizaremos el marco y adoptaremos un enfoque basado en datos:
administre los datos de prueba con una hoja de Excel y encapsule el código;
use ddt para conducir la prueba, y las dos partes son independientes entre sí.

Introducción al módulo openpyxl

openpyxl es un módulo de terceros de python, que puede leer y escribir Excel usando la biblioteca openpyxl.
Antes de comprender el módulo openpyxl, debemos estar familiarizados con la estructura de Excel para comprender mejor cómo funciona Openpyxl en Excel.

Desde el exterior hacia el interior, el primero es un archivo de Excel (nombre). Después de abrir Excel, verá una o más hojas (libros de trabajo) en la parte inferior. Hay muchas celdas en cada hoja. En términos generales, se divide principalmente en tres niveles.

B1

En opnepyxl, un archivo de Excel corresponde a un objeto Libro, una Hoja corresponde a un objeto Hoja de trabajo y una celda corresponde a un objeto Celda. Después de comprender esto, es más claro cómo funciona Openpyxl en Excel.

instalar openpyxl

pip install openpyxl

openpyxl fácil de usar

import openpyxl

if __name__ == '__main__':
    path = 'F:/case/test_case.xlsx'
    # 读取excel文件
    workbook = openpyxl.load_workbook(path)
    # 读取所有sheet
    sheet = workbook.get_sheet_names()
    # 获取某个sheet
    sheet = workbook[sheet[0]]
    # 获取某个cell的值
    cell_val = sheet.cell(row=2, column=2).value
    print(cell_val)

Gestión de casos de uso de Excel

En el proyecto, cree una nueva carpeta: datos y cree un nuevo archivo cases.xlsx debajo de la carpeta para almacenar casos de prueba

B2

La siguiente es una plantilla de diseño de caso de prueba de inicio de sesión simple:

B3

Los resultados reales pueden generarse a partir de esta tabla y los resultados de la prueba pueden escribirse en la tabla (Pasa, No pasa). Responda desde el fondo de la cuenta oficial: plantilla de caso de prueba de interfaz, puede obtener la plantilla de Excel de caso de prueba de interfaz completa.

Ahora que tenemos una plantilla de caso de uso, comenzamos a leer y escribir datos de Excel con el módulo openpyxl. De la siguiente manera, en la carpeta común, cree un nuevo excel_handle.py para encapsular la clase para operar Excel.

B4

excel_handle.py

import openpyxl
class ExcelHandler:
    def __init__(self, file):
        self.file = file
    def open_excel(self, sheet_name):
        """打开Excel、获取sheet"""
        wb = openpyxl.load_workbook(self.file)
        # 获取sheet_name
        sheet = wb[sheet_name]
        return sheet
    def get_header(self, sheet_name):
        """获取header(表头)"""
        wb = self.open_excel(sheet_name)
        header = []
        # 遍历第一行
        for i in wb[1]:
            # 将遍历出来的表头字段加入列表
            header.append(i.value)
        return header
    def read_excel(self, sheet_name):
        """读取所有数据"""
        sheet = self.open_excel(sheet_name)
        rows = list(sheet.rows)
        data = []
        # 遍历从第二行开始的每一行数据
        for row in rows[1:]:
            row_data = []
            # 遍历每一行的每个单元格
            for cell in row:
                row_data.append(cell.value)
                # 通过zip函数将两个列表合并成字典
                data_dict = dict(zip(self.get_header(sheet_name),row_data))
            data.append(data_dict)
        return data
    @staticmethod
    def write_excel(file, sheet_name, row, cloumn,data):
        """Excel写入数据"""
        wb = openpyxl.load_workbook(file)
        sheet = wb[sheet_name]
        sheet.cell(row, cloumn).value = data
        wb.save(file)
        wb.close()
if __name__ == "__main__":
    # 以下为测试代码
    excel = ExcelHandler('../data/cases.xlsx')
    data = excel.read_excel('login')

Introducción y uso del DDT

Introducción de ddt:
Nombre: Pruebas basadas en datos, prueba basada en datos
Función: La ejecución de casos de prueba está impulsada por una colección de datos externos
Idea central: Separación de datos y código de prueba
Escenario de aplicación: Un conjunto de datos externos para realizar la misma operación
Ventajas: Al realizar pruebas En el caso de una gran cantidad de cambios de datos, el código de prueba puede permanecer sin cambios
Proyecto real: Excel almacena datos de prueba, ddt lee datos de prueba en el marco de prueba de unidad (en el caso de prueba)

Suplemento:
El llamado basado en datos se refiere al cambio de datos para impulsar la ejecución de pruebas automatizadas, lo que en última instancia conduce a cambios en los resultados de las pruebas. Para decirlo sin rodeos, es la aplicación de la parametrización.

instalar ddt:

pip install ddt

Uso de ddt:
para saber cómo usar ddt, extraemos tres funciones importantes ddt, desempaquetar y datos del código fuente del módulo ddt.

def ddt(cls):
    """
    Class decorator for subclasses of ``unittest.TestCase``.
    Apply this decorator to the test case class, and then
    decorate test methods with ``@data``.
    For each method decorated with ``@data``, this will effectively create as
    many methods as data items are passed as parameters to ``@data``.
    The names of the test methods follow the pattern
    ``original_test_name_{ordinal}_{data}``. ``ordinal`` is the position of the
    data argument, starting with 1.
    For data we use a string representation of the data value converted into a
    valid python identifier.  If ``data.__name__`` exists, we use that instead.
    For each method decorated with ``@file_data('test_data.json')``, the
    decorator will try to load the test_data.json file located relative
    to the python file containing the method that is decorated. It will,
    for each ``test_name`` key create as many methods in the list of values
    from the ``data`` key.
    """
    for name, func in list(cls.__dict__.items()):
        if hasattr(func, DATA_ATTR):
            for i, v in enumerate(getattr(func, DATA_ATTR)):
                test_name = mk_test_name(name, getattr(v, "__name__", v), i)
                test_data_docstring = _get_test_data_docstring(func, v)
                if hasattr(func, UNPACK_ATTR):
                    if isinstance(v, tuple) or isinstance(v, list):
                        add_test(
                            cls,
                            test_name,
                            test_data_docstring,
                            func,
                            *v
                        )
                    else:
                        # unpack dictionary
                        add_test(
                            cls,
                            test_name,
                            test_data_docstring,
                            func,
                            **v
                        )
                else:
                    add_test(cls, test_name, test_data_docstring, func, v)
            delattr(cls, name)
        elif hasattr(func, FILE_ATTR):
            file_attr = getattr(func, FILE_ATTR)
            process_file_data(cls, name, func, file_attr)
            delattr(cls, name)
    return cls
def unpack(func):
    """
    Method decorator to add unpack feature.
    """
    setattr(func, UNPACK_ATTR, True)
    return func
def data(*values):
    """
    Method decorator to add to your test methods.
    Should be added to methods of instances of ``unittest.TestCase``.
    """
    global index_len
    index_len = len(str(len(values)))
    return idata(values)

ddt:
clase de decoración, que es una clase heredada de TestCase.
datos:
Decora el método de prueba. Los parámetros son una serie de valores.

desempaquetar:
se utiliza al pasar estructuras de datos complejas. Por ejemplo, si usa una tupla o una lista, después de agregar desempaquetar, ddt asignará automáticamente la tupla o la lista a varios parámetros, y los diccionarios también se pueden manejar de esta manera; cuando no se agrega desempaquetar, solo un parámetro del método se puede llenar

Ejemplo:
test_ddt.py

import unittest
import ddt
# 装饰类
@ddt.ddt
class DdtDemo(unittest.TestCase):
    def setUp(self):
        pass
    def tearDown(self):
        pass
    
    # 装饰方法
    @ddt.data(("15312344578", "12345678"), ("15387654321", "12345678"))
    @ddt.unpack
    def test_ddt(self, username,password):
        print(username,password)
if __name__ == '__main__':
    unittest.main(verbosity=2)

El resultado de la operación es:

Ran 2 tests in 0.001s
OK
15312344578 12345678
15387654321 12345678

test_login.py

import unittest
from common.requests_handler import RequestsHandler
from common.excel_handler import ExcelHandler
import ddt
import json
@ddt.ddt
class TestLogin(unittest.TestCase):
    # 读取excel中的数据
    excel = ExcelHandler('../data/cases.xlsx')
    case_data = excel.read_excel('login')
    print(case_data)
    def setUp(self):
        # 请求类实例化
        self.req = RequestsHandler()
    def tearDown(self):
        # 关闭session管理器
        self.req.close_session()
    @ddt.data(*case_data)
    def test_login_success(self,items):
        # 请求接口
        res = self.req.visit(method=items['method'],url=items['url'],json=json.loads(items['payload']),
                             headers=json.loads(items['headers']))
        try:
            # 断言:预期结果与实际结果对比
            self.assertEqual(res['code'], items['expected_result'])
            result = 'Pass'
        except AssertionError as e:
            result = 'Fail'
            raise e
        finally:
            # 将响应的状态码,写到excel的第9列,即写入返回的状态码
            TestLogin.excel.write_excel("../data/cases.xlsx", 'login', items['case_id'] + 1, 9, res['code'])
            # 如果断言成功,则在第10行(测试结果)写入Pass,否则,写入Fail
            TestLogin.excel.write_excel("../data/cases.xlsx", 'login', items['case_id'] + 1, 10, result)
if __name__ == '__main__':
    unittest.main()
El siguiente es el diagrama de sistema de arquitectura de conocimiento de aprendizaje de ingeniero de prueba de software más completo en 2023 que compilé

1. De la entrada al dominio de la programación en Python

Por favor agregue una descripción de la imagen

2. Proyecto de automatización de interfaz de combate real.

Por favor agregue una descripción de la imagen

3. Combate real del proyecto de automatización web

Por favor agregue una descripción de la imagen

4. Combate real del proyecto de automatización de aplicaciones

Por favor agregue una descripción de la imagen

5. Hoja de vida de los fabricantes de primer nivel

Por favor agregue una descripción de la imagen

6. Probar y desarrollar el sistema DevOps

Por favor agregue una descripción de la imagen

7. Herramientas de prueba automatizadas de uso común

Por favor agregue una descripción de la imagen

Ocho, prueba de rendimiento JMeter

Por favor agregue una descripción de la imagen

9. Resumen (pequeña sorpresa al final)

No te detengas, no tengas miedo al fracaso, el camino de la lucha puede ser solitario y largo, pero la persistencia y el trabajo duro iluminarán el camino a seguir. La realización de los sueños requiere sudor y lágrimas, mientras la llama de la pasión se encienda en tu corazón, puedes crear tu propia vida brillante.

Avanza con valentía, desafía las dificultades y la fuerza de la lucha crea grandes logros. Impulsado por la pasión, pavimentado con trabajo duro, el camino para perseguir los sueños nunca es fácil, pero cada persistencia nos acercará un paso más al éxito.

No importa cuán decadente haya sido el ayer, hoy es una oportunidad para empezar de nuevo. La lucha no es sólo un proceso de trabajo duro, sino también el poder de cambiar el destino. Solo creyendo en la capacidad de uno y persistiendo en la búsqueda puede uno florecer a través del trabajo duro y crear una vida orgullosa.

Supongo que te gusta

Origin blog.csdn.net/m0_70102063/article/details/132209665
Recomendado
Clasificación