Acabado de hígado explosivo, pruebas automatizadas de Python - Empaquetado de combate real parametrizado Pytest, un artículo para pasar...


prefacio

parametrizar?
El entendimiento popular es que al definir una clase de prueba o una función de prueba, se pueden pasar parámetros correspondientes a diferentes casos de prueba, para ejecutar múltiples casos de prueba.

Por ejemplo:
para probar la interfaz de inicio de sesión, asumiendo que hay 3 casos de uso, iniciar sesión con la cuenta y la contraseña correctas, iniciar sesión con la cuenta correcta y la contraseña incorrecta e iniciar sesión con la cuenta y la contraseña incorrectas, solo necesitamos definir una función de prueba de inicio de sesión test_login (), y luego use estos 3 elementos Use los parámetros correspondientes al caso para llamar a test_login().

DDT se puede usar para la parametrización en unittest, y también se proporciona un método de parametrización muy conveniente en pytest, es decir, se usa el decorador @pytest.mark.parametrize().

Generalmente escrito como pytest.mark.parametrize("argnames", argvalues).
Entre ellos:
argnames es el nombre del parámetro, que puede ser único o múltiple, y los métodos de escritura múltiple son "argname1, argname2,...";
argvalues ​​es el valor del parámetro, y el tipo debe ser list (puede ser un tupla para un solo parámetro, y debe ser una tupla para la lista de múltiples parámetros, por lo que es mejor unificar);

Por ejemplo, existen las siguientes interfaces:
Información de la interfaz de inicio de sesión solicitada:

接口url:http://127.0.0.1:5000/login
请求方式:post
请求参数:
响应信息:

1. Un solo parámetro

Cuando solo se necesita pasar un parámetro, el ejemplo es el siguiente:

# 待测试函数
def sum(a):
    return a+1

# 单个参数
data = [1, 2, 3, 4]
@pytest.mark.parametrize("item", data)
def test_add(item):
    actual = sum(item)
    print("\n{}".format(actual))
    # assert actual == 3

if __name__ == '__main__':
    pytest.main()

Nota:
El primer parámetro en @pytest.mark.parametrize() debe tener la forma de una cadena para identificar los parámetros de entrada de la función de prueba.Como en el ejemplo anterior, el parámetro pasado en la función de prueba definida test_login() es elemento con nombre, entonces el primer parámetro de @pytest.mark.parametrize() es "elemento".

El resultado de la operación es el siguiente:

rootdir: E:\blog\python接口自动化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 items

test_case_2.py::test_add[1] PASSED                                       [ 25%]
2

test_case_2.py::test_add[2] PASSED                                       [ 50%]
3

test_case_2.py::test_add[3] PASSED                                       [ 75%]
4

test_case_2.py::test_add[4] PASSED                                       [100%]
5

============================== 4 passed in 0.02s ==============================

Como se puede ver en los resultados, la función de prueba pasó los parámetros en datos respectivamente y se ejecutó 5 veces en total.

2. Múltiples parámetros

Cuando el caso de prueba necesita pasar múltiples parámetros, el primer parámetro de @pytest.mark.parametrize() también es una cadena, y los múltiples parámetros del caso de prueba están separados por comas.

Ejemplo:

import pytest
import requests
import json

# 列表嵌套元组
data = [("lilei", "123456"), ("hanmeimei", "888888")]
# 列表嵌套列表
# data = [["lilei", "123456"], ["hanmeimei", "888888"]]

@pytest.mark.parametrize("username, password", data)
def test_login(username, password):
    headers = {
    
    "Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
    
    
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    assert res['code'] == 1000


if __name__ == '__main__':
    pytest.main()

Nota:
El formato de los datos en el código puede ser una lista anidada o una tupla anidada de lista. Cada lista o tupla de la lista representa un conjunto de parámetros de solicitud independientes.
"nombre de usuario, contraseña" no se puede escribir como "nombre de usuario", "contraseña".

El resultado de la operación es el siguiente:

A1

De los resultados, también podemos ver los parámetros pasados ​​en cada ejecución, como se muestra en la parte subrayada.

El ejemplo aquí son 2 parámetros. Cuando se pasan 3 o más parámetros, el método de escritura es el mismo. Asegúrese de prestar atención a la correspondencia uno a uno entre ellos, como se muestra en la siguiente figura:

A2

3. Parametrizar la clase de prueba

Los ejemplos anteriores son todas funciones de prueba parametrizadas, entonces, ¿cómo parametrizar clases de prueba?

De hecho, la parametrización de la clase de prueba es parametrizar los métodos de prueba en la clase de prueba.

La cantidad de parámetros identificados en @pytest.mark.parametrize() debe ser consistente con los parámetros del método de prueba en la clase. Los ejemplos son los siguientes:

# 将登陆接口请求单独进行了封装,仅仅只是为了方便下面的示例
def login(username, password):
    headers = {
    
    "Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
    
    
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    return res

# 测试类参数化
data = [
    ("lilei", "123456"), ("hanmeimei", "888888")
]
@pytest.mark.parametrize("username, password", data)
class TestLogin:
    def test_login_01(self, username, password):
        res = login(username, password)
        assert res['code'] == 1000

    def test_login_02(self, username, password):
        res = login(username, password)
        assert res['msg'] == "登录成功!"

if __name__ == '__main__':
    pytest.main(["-s"])

El resultado de la operación es el siguiente:

A3

Se puede ver a partir de los resultados que se realizan un total de 4 ejecuciones, y cada método de prueba en la clase de prueba se ejecuta 2 veces, es decir, cada método de prueba ejecuta cada conjunto de parámetros en los datos una vez.

Nota:
Aquí aún debemos enfatizar la relación correspondiente de los parámetros, es decir, el primer parámetro en @pytest.mark.parametrize() debe corresponder uno a uno con los parámetros del método de prueba en la clase de prueba.

4. Combinación de parámetros

En el proceso de escribir casos de prueba, a veces es necesario combinar parámetros para solicitudes de interfaz. Por ejemplo, en la interfaz de inicio de sesión del ejemplo, los nombres de usuario incluyen lilei y hanmeimei, y las contraseñas incluyen 123456 y 888888. Hay cuatro situaciones para combinándolos:

{
    
    "username": "lilei", "password": "123456"}
{
    
    "username": "lilei", "password": "888888"}
{
    
    "username": "hanmeimei", "password": "123456"}
{
    
    "username": "hanmeimei", "password": "888888"}

@pytest.mark.parametrize() también proporciona una función de combinación de parámetros de este tipo, el ejemplo de formato de escritura es el siguiente:

import pytest
import requests
import json


username = ["lilei", "hanmeimei"]
password = ["123456", "888888"]

@pytest.mark.parametrize("password", password)
@pytest.mark.parametrize("username", username)
def test_login(username, password):
    headers = {
    
    "Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
    
    
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    assert res['code'] == 1000
	
	
if __name__ == '__main__':
    pytest.main()

El resultado de la operación es el siguiente:

rootdir: E:\blog\python接口自动化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 items

test_case_5.py::test_login[lilei-123456] PASSED                          [ 25%]
test_case_5.py::test_login[lilei-888888] FAILED                          [ 50%]
test_case_5.py::test_login[hanmeimei-123456] FAILED                      [ 75%]
test_case_5.py::test_login[hanmeimei-888888] PASSED                      [100%]
=========================== short test summary info ===========================
FAILED test_case_5.py::test_login[lilei-888888] - assert 1001 == 1000
FAILED test_case_5.py::test_login[hanmeimei-123456] - assert 1001 == 1000
========================= 2 failed, 2 passed in 0.18s =========================

Se puede ver en los resultados que hay 4 combinaciones de 2 nombres de usuario y 2 contraseñas, y se ejecutan 4 veces en total. Si hay 3 nombres de usuario y 2 contraseñas, entonces hay 6 combinaciones de parámetros y así sucesivamente.

Nota:
Los casos de prueba en los ejemplos anteriores son solo ejemplos, y el script de prueba de la interfaz de inicio de sesión y los datos de prueba en el proyecto real serán diferentes.

5. Aumente la legibilidad de los resultados de las pruebas

A partir de los resultados de ejecución del ejemplo, podemos ver que para distinguir los resultados de ejecución parametrizados, los nombres de casos de ejecución compuestos por parámetros se mostrarán en los resultados, y es muy conveniente ver qué casos de uso de combinaciones de parámetros se ejecutan. .

Ejemplo:

A5

Pero esto es solo una pantalla simple. Si hay muchos y complicados parámetros, no es lo suficientemente claro como para mostrarlo de esta manera. Es necesario agregar algunas explicaciones para que quede claro de un vistazo.

Por lo tanto, hay dos formas de personalizar los resultados de visualización de la parte subrayada en la figura anterior en @pytest.mark.parametrize(), es decir, usar los ID de parámetros proporcionados por @pytest.mark.parametrize() para personalizar, o use pytest.param La identificación del parámetro en () está personalizada.

ids (recomendado)
Ejemplos de cómo usar ids son los siguientes:

import pytest
import requests
import json


data = [("lilei", "123456"), ("hanmeimei", "888888")]
ids = ["username:{}-password:{}".format(username, password) for username, password in data]
@pytest.mark.parametrize("username, password", data, ids=ids)
def test_login(username, password):
    headers = {
    
    "Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
    
    
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    assert res['code'] == 1000
    

if __name__ == '__main__':
    pytest.main()

Se puede ver por el método de escritura que ids es una lista, y su longitud es consistente con el número de grupos de combinaciones de parámetros.

El resultado de la operación es el siguiente:

A6

Al comparar los resultados de ejecución anteriores, podemos ver la diferencia entre los resultados de ejecución personalizados de ids y los resultados de ejecución predeterminados. Durante el uso, debe personalizarse de acuerdo con la situación real.

Un ejemplo de cómo usar id
es el siguiente:

import pytest
import requests
import json


data = [
    pytest.param("lilei", "123456", id="correct username and correct password"),
    pytest.param("lilei", "111111", id="correct user name and wrong password")
]

@pytest.mark.parametrize("username, password", data)
def test_login(username, password):
    headers = {
    
    "Content-Type": "application/json;charset=utf8"}
    url = "http://127.0.0.1:5000/login"
    _data = {
    
    
        "username": username,
        "password": password
    }
    res = requests.post(url=url, headers=headers, json=_data).text
    res = json.loads(res)
    assert res['code'] == 1000


if __name__ == '__main__':
    pytest.main()

El resultado de la operación es el siguiente:

A7

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)

La lucha es un largo viaje, y el dolor y el sufrimiento son solo pruebas que conducen al éxito. No tengas miedo a las dificultades, aférrate a tus creencias y riega con sudor las flores de tus sueños. ¡Cree en ti mismo y avanza con valentía, crearás tu propio brillo y dejarás una huella sin remordimientos!

La llama de la persistencia quema el corazón, y el coraje inquebrantable disipa la oscuridad. Deja ir tu miedo, enfrenta desafíos y sigue esforzándote. Todo esfuerzo forja tenacidad, y toda lucha abre un nuevo capítulo. Avanza con valentía y persigue tus sueños.

En el escenario de la vida, sólo la lucha puede componer un movimiento brillante. No tengas miedo a las dificultades, pero enfrenta los desafíos con valentía. ¡Sigue trabajando duro, nunca te rindas, cree en tu propia fuerza, crearás una vida inesperada y maravillosa!

Supongo que te gusta

Origin blog.csdn.net/shuang_waiwai/article/details/132230699
Recomendado
Clasificación