Tutorial de PyTest: ¿Qué es PyTest? (con ejemplos)

⚡ Resumen inteligente

Pytest es un Python Marco de pruebas que facilita la escritura de pruebas sencillas y escalables para bases de datos, API e interfaces de usuario. Admite fixtures, parametrización, marcadores, ejecuciones paralelas e informes detallados de aserciones, desde pruebas unitarias básicas hasta pruebas funcionales complejas.

  • 🔘 Instalación: El comando pip install pytest agrega el framework, y py.test -h confirma la configuración imprimiendo la salida de ayuda.
  • ☑️ Descubrimiento de pruebas: Pytest recopila automáticamente los archivos llamados test_*.py o *_test.py y los métodos cuyos nombres comienzan con test.
  • Afirmaciones: Las sentencias assert simples informan de un AssertionError claro con los valores comparados cuando falla una comprobación.
  • 🧪 Luminarias: El decorador @pytest.fixture proporciona datos de configuración reutilizables que se comparten entre archivos a través de un archivo conftest.py.
  • 🛠️ Carreras selectivas: Los marcadores, el filtro de subcadenas -k y la parametrización ejecutan subconjuntos específicos o la misma prueba en múltiples entradas.
  • 🤖 Flujos de trabajo de IA: Los equipos de aprendizaje automático utilizan pytest para validar las canalizaciones de datos y los resultados de los modelos, y Copilot puede elaborar casos de prueba.

Tutorial de Pytest

Pytest es uno de los marcos de prueba más utilizados en el Python Ecosistema. Mantiene el código de prueba breve y legible, detecta las pruebas automáticamente y se expande desde una primera aserción hasta convertirse en un conjunto completo de pruebas para bases de datos, API e interfaces de usuario. Las secciones siguientes explican la instalación, las aserciones, los fixtures, los marcadores, la parametrización y las ejecuciones paralelas con ejemplos prácticos.

¿Qué es Pytest?

Pytest es un marco de pruebas que te permite escribir código de prueba utilizando el Python Lenguaje de programación. Ayuda a escribir casos de prueba sencillos y escalables para bases de datos, API e incluso interfaces de usuario. Pytest se utiliza principalmente para escribir pruebas de API y abarca desde pruebas unitarias simples hasta pruebas funcionales complejas.

¿Por qué usar Pytest?

Algunas de las ventajas de pytest son:

  • Es muy fácil empezar a usarlo, gracias a su sintaxis sencilla y clara.
  • Puede ejecutar pruebas en paralelo.
  • Puede ejecutar una prueba específica o un subconjunto de pruebas.
  • Detecta automáticamente las pruebas.
  • Puede omitir las pruebas.
  • Fuente abierta.

Cómo instalar Pytest

A continuación se describe el proceso para instalar pytest:

Paso 1) Puedes instalar pytest con el siguiente comando.

pip install pytest==2.9.1

Una vez finalizada la instalación, puede confirmarla con el siguiente comando.

py.test -h

Esto mostrará la ayuda.

Instala pytest y consulta la salida de la ayuda.

Primer ejemplo básico de Pytest

Ahora aprenderás a usar pytest con un ejemplo básico.

Crea una carpeta llamada study_pytest. Dentro de esta carpeta crearás los archivos de prueba. Accede a ella desde la línea de comandos. Crea un archivo llamado test_sample1.py dentro de la carpeta.

Crea el primer archivo de prueba básico de pytest.

Añade el siguiente código y guarda.

import pytest
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed"
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed" 

Ejecuta la prueba usando el siguiente comando.

py.test

Obtendrás el siguiente resultado.

test_sample1.py F.
============================================== FAILURES ========================================
____________________________________________ test_sample1 ______________________________________
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed"
E       AssertionError: test failed
E       assert 5 == 6
test_sample1.py:6: AssertionError

Salida de error de la prueba Pytest

Aquí, en test_sample1.py F., la letra F indica fallo y el punto (.) indica éxito. En la sección de fallos, puede ver el/los método(s) que falló(n) y la línea donde se produjo el fallo. Aquí x==y significa 5==6, lo cual es falso.

A continuación, aprenderás sobre las aserciones en pytest.

Aserciones en Pytest

Las aserciones de Pytest son comprobaciones que devuelven un valor verdadero o falso. En Pytest, si una aserción falla en un método de prueba, la ejecución de dicho método se detiene. El código restante de ese método no se ejecuta y Pytest continúa con el siguiente método de prueba.

Ejemplos de aserciones de Pytest:

assert "hello" == "Hai" is an assertion failure.
assert 4==4 is a successful assertion
assert True is a successful assertion
assert False is an assertion failure.

Considera lo siguiente.

assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

Coloca este código en test_file1_method1() en lugar de la aserción que aparece a continuación.

assert x == y,"test failed"

Ejecutar la prueba dará como resultado el error. AssertionError: prueba fallida x=5 y=6.

Cómo Pytest identifica los archivos de prueba y los métodos de prueba

Por defecto, pytest identifica solo los nombres de archivo que comienzan con prueba_ o terminando con _prueba como los archivos de prueba. Sin embargo, podemos mencionar otros nombres de archivo explícitamente (explicado más adelante). Pytest requiere que los nombres de los métodos de prueba comiencen con compruébaloTodos los demás nombres de métodos se ignoran, incluso si solicitamos explícitamente que se ejecuten esos métodos.

Vea algunos ejemplos de nombres de archivo válidos e inválidos para pytest.

test_login.py - valid
login_test.py - valid
testlogin.py -invalid
logintest.py -invalid

Nota: Sí, podemos indicarle explícitamente a pytest que seleccione testlogin.py y logintest.py.

Vea algunos ejemplos de métodos de prueba de pytest válidos e inválidos.

def test_file1_method1(): - valid
def testfile1_method1(): - valid
def file1_method1(): - invalid	

Nota: Aunque mencionemos explícitamente file1_method1(), pytest no ejecutará este método.

Ejecute varias pruebas desde un archivo específico y varios archivos

Actualmente, dentro de la carpeta study_pytest, tenemos un archivo llamado test_sample1.py. Supongamos que tenemos varios archivos, por ejemplo, test_sample2.py y test_sample3.py. Para ejecutar todas las pruebas de todos los archivos de la carpeta y sus subcarpetas, basta con ejecutar el comando pytest.

py.test

Esto procesará todos los archivos cuyos nombres comiencen con test_ y los que terminen con _test en esa carpeta y en las subcarpetas que contiene.

Para ejecutar pruebas solo desde un archivo específico, podemos usar py.test. .

py.test test_sample1.py

Ejecuta un subconjunto de la prueba completa con Pytest.

A veces no queremos ejecutar todo el conjunto de pruebas. Pytest nos permite ejecutar pruebas específicas. Podemos hacerlo de dos maneras:

  • Grouping de nombres de prueba por coincidencia de subcadenas.
  • Grouping de pruebas por marcadores.

Ya tenemos test_sample1.py. Crea un archivo llamado test_sample2.py y agrega el siguiente código.

def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

Así que actualmente tenemos lo siguiente.

• test_sample1.py
• test_file1_method1()
• test_file1_method2()
• test_sample2.py
• test_file2_method1()
• test_file2_method2()

Opción 1) Ejecutar pruebas mediante coincidencia de subcadenas

Aquí, para ejecutar todas las pruebas que tengan method1 en su nombre, tenemos que ejecutar el siguiente comando.

py.test -k method1 -v
-k <expression> is used to represent the substring to match
-v increases the verbosity

Así que ejecutar py.test -k method1 -v te dará el siguiente resultado.

test_sample2.py::test_file2_method1 FAILED
test_sample1.py::test_file1_method1 FAILED

============================================== FAILURES ==============================================
_________________________________________ test_file2_method1 _________________________________________
    def test_file2_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample2.py:5: AssertionError

_________________________________________ test_file1_method1 _________________________________________
    @pytest.mark.only
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
test_sample1.py:8: AssertionError

================================= 2 tests deselected by '-kmethod1' ==================================
=============================== 2 failed, 2 deselected in 0.02 seconds ===============================

Aquí se puede ver, hacia el final, 2 pruebas deseleccionadas por '-kmethod1', que son test_file1_method2 y test_file2_method2.

Prueba a correr con varias combinaciones como las siguientes.

py.test -k method -v - will run all the four methods
py.test -k methods -v – will not run any test as there is no test name matches the substring 'methods'

Opción 2) Ejecutar pruebas por marcadores

Pytest nos permite establecer varios atributos para los métodos de prueba usando marcadores de pytest, @pytest.mark. Para usar marcadores en el archivo de prueba, necesitamos importar pytest en los archivos de prueba. Aquí aplicaremos diferentes nombres de marcadores a los métodos de prueba y ejecutaremos pruebas específicas según los nombres de los marcadores. Podemos definir los marcadores en cada nombre de prueba usando lo siguiente.

@pytest.mark.<name>.			

Estamos definiendo los marcadores set1 y set2 en los métodos de prueba, y ejecutaremos la prueba utilizando los nombres de los marcadores. Actualice los archivos de prueba con el siguiente código.

prueba_muestra1.py

import pytest
@pytest.mark.set1
def test_file1_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set2
def test_file1_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

prueba_muestra2.py

import pytest
@pytest.mark.set1
def test_file2_method1():
	x=5
	y=6
	assert x+1 == y,"test failed"
	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)

@pytest.mark.set1
def test_file2_method2():
	x=5
	y=6
	assert x+1 == y,"test failed"

Podemos ejecutar la prueba marcada con el siguiente comando.

py.test -m <name>
-m <name> mentions the marker name

Ejecuta py.test -m set1. Esto ejecutará los métodos test_file1_method1, test_file2_method1 y test_file2_method2. Ejecutar py.test -m set2 ejecutará test_file1_method2.

Ejecuta pruebas en paralelo con Pytest.

Normalmente, un conjunto de pruebas contiene varios archivos de prueba y cientos de métodos de prueba, lo que requiere un tiempo considerable para su ejecución. Pytest nos permite ejecutar pruebas en paralelo. Para ello, primero debemos instalar pytest-xdist ejecutando el siguiente comando.

pip install pytest-xdist

Ejecuta las pruebas en paralelo con pytest-xdist.

Ahora puedes ejecutar las pruebas con el siguiente comando.

py.test -n 4

Aquí, -n Ejecuta las pruebas utilizando varios trabajadores. En el comando anterior, habrá cuatro trabajadores para ejecutar las pruebas.

Calendario de Pytest

Los fixtures se utilizan cuando queremos ejecutar algún código antes de cada método de prueba. Así, en lugar de repetir el mismo código en cada prueba, definimos fixtures. Normalmente, los fixtures se utilizan para inicializar las conexiones a la base de datos y pasar la base de datos. URLy así sucesivamente. Un método se marca como un fixture de pytest marcándolo con lo siguiente.

@pytest.fixture

Un método de prueba puede usar un fixture de pytest mencionándolo como parámetro de entrada. Cree un nuevo archivo llamado test_basic_fixture.py con el siguiente código.

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

Aquí:

  • Tenemos un fixture llamado supply_AA_BB_CC. Este método devuelve una lista de tres valores.
  • Tenemos tres métodos de prueba que comparan cada uno de los valores.

Cada una de las funciones de prueba tiene un argumento de entrada cuyo nombre coincide con un fixture disponible. Pytest invoca entonces el método del fixture correspondiente, y los valores devueltos se almacenan en el argumento de entrada, en este caso la lista [25,35,45]. Los elementos de la lista se utilizan posteriormente en los métodos de prueba para la comparación. Ahora ejecuta la prueba y observa el resultado.

 py.test test_basic_fixture
test_basic_fixture.py::test_comparewithAA FAILED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithBB PASSED                                                                                                                                                                                       
test_basic_fixture.py::test_comparewithCC FAILED
                                                                                                                                                                                       
============================================== FAILURES ==============================================
_________________________________________ test_comparewithAA _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithAA(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"
E    AssertionError: aa and zz comparison failed
E    assert 25 == 35
test_basic_fixture.py:10: AssertionError

_________________________________________ test_comparewithCC _________________________________________
supply_AA_BB_CC = [25, 35, 45]
    def test_comparewithCC(supply_AA_BB_CC):
    	zz=35
>   	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
E    AssertionError: cc and zz comparison failed
E    assert 45 == 35
test_basic_fixture.py:16: AssertionError
================================= 2 failed, 1 passed in 0.05 seconds =================================

La prueba test_comparewithBB pasa, ya que zz=BB=35, y las dos pruebas restantes fallan.

El método fixture tiene un alcance únicamente dentro del archivo de prueba donde se define. Si intentamos acceder al fixture en algún otro archivo de prueba, obtendremos un error que indica fixture. 'suministro_AA_BB_CC' no encontrado para los métodos de prueba en los otros archivos.

Para usar el mismo fixture con varios archivos de prueba, creamos métodos fixture en un archivo llamado conftest.py. Veamos esto con el siguiente ejemplo de pytest. Crea tres archivos, conftest.py, test_basic_fixture.py y test_basic_fixture2.py, con el siguiente código.

concurso.py

import pytest
@pytest.fixture
def supply_AA_BB_CC():
	aa=25
	bb =35
	cc=45
	return [aa,bb,cc]

test_basic_fixture.py

import pytest
def test_comparewithAA(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC(supply_AA_BB_CC):
	zz=35
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

test_basic_fixture2.py

import pytest
def test_comparewithAA_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed"

def test_comparewithBB_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed"

def test_comparewithCC_file2(supply_AA_BB_CC):
	zz=25
	assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"

Pytest buscará primero el fixture en el archivo de prueba y, si no lo encuentra, lo buscará en conftest.py. Ejecute la prueba con py.test -k test_comparewith -v para obtener el resultado que se muestra a continuación.

test_basic_fixture.py::test_comparewithAA FAILED  
test_basic_fixture.py::test_comparewithBB PASSED 
test_basic_fixture.py::test_comparewithCC FAILED 
test_basic_fixture2.py::test_comparewithAA_file2 PASSED 
test_basic_fixture2.py::test_comparewithBB_file2 FAILED 
test_basic_fixture2.py::test_comparewithCC_file2 FAILED

Prueba parametrizada de Pytest

El objetivo de parametrizar una prueba es ejecutarla con múltiples conjuntos de argumentos. Esto se logra con `@pytest.mark.parametrize`. Lo veremos en el siguiente ejemplo de pytest. Aquí pasaremos tres argumentos a un método de prueba. Este método sumará los dos primeros argumentos y comparará el resultado con el tercero. Crea el archivo de prueba `test_addition.py` con el siguiente código.

import pytest
@pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
def test_add(input1, input2, output):
	assert input1+input2 == output,"failed"

Aquí, el método de prueba acepta tres argumentos: input1, input2 y output. Suma input1 e input2 y compara la suma con output. Ejecutemos la prueba con py.test -k test_add -v y veamos el resultado.

test_addition.py::test_add[5-5-10] PASSED                                                                                                                                                                                              
test_addition.py::test_add[3-5-12] FAILED                                                                                                                                                                                              
============================================== FAILURES ==============================================
__________________________________________ test_add[3-5-12] __________________________________________
input1 = 3, input2 = 5, output = 12
    @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)])
    def test_add(input1, input2, output):
>   	assert input1+input2 == output,"failed"
E    AssertionError: failed
E    assert (3 + 5) == 12
test_addition.py:5: AssertionError

Puedes ver que las pruebas se ejecutaron dos veces, una comprobando que 5+5 == 10 y la otra comprobando que 3+5 == 12.

test_addition.py::test_add[5-5-10] PASADO

test_addition.py::test_add[3-5-12] FALLÓ

Pruebas con Pytest Xfail y Skip Tests

Habrá algunas situaciones en las que no queramos ejecutar una prueba, o una caso de prueba no es relevante en un momento determinado. En esas situaciones, tenemos la opción de hacer que la prueba falle o de omitir las pruebas. La prueba que falló se ejecutará, pero no se contará como parte de las pruebas fallidas o aprobadas. No habrá tracSe mostrará un mensaje de error si esa prueba falla. Podemos marcar las pruebas como fallidas usando @pytest.mark.xfail. Saltarping Una prueba significa que la prueba no se ejecutará. Podemos omitir pruebas usando @pytest.mark.skip. Edita el archivo test_addition.py con el siguiente código.

import pytest
@pytest.mark.skip
def test_add_1():
	assert 100+200 == 400,"failed"

@pytest.mark.skip
def test_add_2():
	assert 100+200 == 300,"failed"

@pytest.mark.xfail
def test_add_3():
	assert 15+13 == 28,"failed"

@pytest.mark.xfail
def test_add_4():
	assert 15+13 == 100,"failed"

def test_add_5():
	assert 3+2 == 5,"failed"

def test_add_6():
	assert 3+2 == 6,"failed"

Aquí:

  • test_add_1 y test_add_2 se omiten y no se ejecutarán.
  • Las pruebas test_add_3 y test_add_4 han fallado. Estas pruebas se ejecutarán y formarán parte de las pruebas que fallan (en caso de fallo) o que pasan (en caso de éxito). No habrá ninguna tracDevolución electrónica por fallos.
  • Se ejecutarán test_add_5 y test_add_6, y test_add_6 informará de un fallo con un traceback mientras test_add_5 pasa.

Ejecuta la prueba con py.test test_addition.py -v y observa el resultado.

test_addition.py::test_add_1 SKIPPED
test_addition.py::test_add_2 SKIPPED
test_addition.py::test_add_3 XPASS
test_addition.py::test_add_4 xfail
test_addition.py::test_add_5 PASSED
test_addition.py::test_add_6 FAILED

============================================== FAILURES ==============================================
_____________________________________________ test_add_6 _____________________________________________
    def test_add_6():
>   	assert 3+2 == 6,"failed"
E    AssertionError: failed
E    assert (3 + 2) == 6
test_addition.py:24: AssertionError

================ 1 failed, 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.07 seconds =================

Resultados en formato XML

Podemos generar resultados de prueba en formato XML, que luego podemos enviar a servidores de integración continua para su posterior procesamiento. Esto se puede hacer con el comando `py.test test_sample1.py -v –junitxml=”result.xml”`. El archivo `result.xml` registrará el resultado de la ejecución de la prueba. A continuación, encontrará un ejemplo de `result.xml`.

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="0" failures="1" name="pytest" skips="0" tests="2" time="0.046">
   <testcase classname="test_sample1" file="test_sample1.py" line="3" name="test_file1_method1" time="0.001384973526">
     <failure message="AssertionError:test failed because x=5 y=6 assert 5 ==6">
    @pytest.mark.set1
    def test_file1_method1():
    	x=5
    	y=6
       	assert x+1 == y,"test failed"
>      	assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
E       AssertionError: test failed because x=5 y=6
E       assert 5 == 6
         test_sample1.py:9: AssertionError
    </failure>
   </testcase>
   <testcase classname="test_sample1" file="test_sample1.py" line="10" name="test_file1_method2" time="0.000830173492432" />
</testsuite>

De Podemos ver un total de dos pruebas, de las cuales una ha fallado. Debajo de eso, puede ver los detalles sobre cada prueba ejecutada en el etiqueta.

Marco de trabajo Pytest para probar una API

Ahora crearemos un pequeño framework pytest para probar una API. La API utilizada aquí es gratuita. requisitos.inEste sitio web simplemente proporciona una API que se puede probar y no almacena nuestros datos. Aquí escribiremos algunas pruebas para lo siguiente:

  • Listado de algunos usuarios.
  • Iniciar sesión con usuarios.

Crea los siguientes archivos con el código proporcionado. Primero, conftest.py tiene un fixture que proporcionará la base. URL para todos los métodos de prueba.

import pytest
@pytest.fixture
def supply_url():
	return "https://reqres.in/api"

A continuación, el archivo test_list_user.py contiene los métodos de prueba para listar los usuarios válidos e inválidos.

  • La función test_list_valid_user comprueba si se ha obtenido un usuario válido y verifica la respuesta.
  • La función test_list_invaliduser comprueba si se ha solicitado un usuario no válido y verifica la respuesta.
import pytest
import requests
import json
@pytest.mark.parametrize("userid, firstname",[(1,"George"),(2,"Janet")])
def test_list_valid_user(supply_url,userid,firstname):
	url = supply_url + "/users/" + str(userid)
	resp = requests.get(url)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['data']['id'] == userid, resp.text
	assert j['data']['first_name'] == firstname, resp.text

def test_list_invaliduser(supply_url):
	url = supply_url + "/users/50"
	resp = requests.get(url)
	assert resp.status_code == 404, resp.text

A continuación, el archivo test_login_user.py contiene los métodos de prueba para comprobar la funcionalidad de inicio de sesión.

  • La función test_login_valid comprueba si el intento de inicio de sesión con un correo electrónico y una contraseña es válido.
  • La función test_login_no_password prueba el intento de inicio de sesión no válido sin proporcionar una contraseña.
  • La prueba test_login_no_email comprueba el intento de inicio de sesión no válido sin proporcionar una dirección de correo electrónico.
import pytest
import requests
import json
def test_login_valid(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com','password':'something'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 200, resp.text
	assert j['token'] == "QpwL5tke4Pnpja7X", resp.text

def test_login_no_password(supply_url):
	url = supply_url + "/login/" 
	data = {'email':'test@test.com'}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing password", resp.text

def test_login_no_email(supply_url):
	url = supply_url + "/login/" 
	data = {}
	resp = requests.post(url, data=data)
	j = json.loads(resp.text)
	assert resp.status_code == 400, resp.text
	assert j['error'] == "Missing email or username", resp.text

Ejecuta la prueba usando py.test -v y observa el resultado a continuación.

test_list_user.py::test_list_valid_user[1-George] PASSED                                                                                                                                                                               
test_list_user.py::test_list_valid_user[2-Janet] PASSED                                                                                                                                                                                
test_list_user.py::test_list_invaliduser PASSED                                                                                                                                                                                        
test_login_user.py::test_login_valid PASSED                                                                                                                                                                                            
test_login_user.py::test_login_no_password PASSED                                                                                                                                                                                      
test_login_user.py::test_login_no_email PASSED

Actualiza las pruebas y experimenta con diferentes resultados.

Preguntas Frecuentes

Ambos corren Python Las pruebas son diferentes, pero pytest utiliza sentencias assert simples, requiere menos código repetitivo y ofrece fixtures, marcadores y parametriza. Unittest viene con la biblioteca estándar y sigue el estilo xUnit basado en clases. Pytest aún puede ejecutar casos de prueba de unittest existentes.

Utilice la sintaxis de ID de nodo con dos puntos dobles: pytest test_sample1.py::test_file1_method1. Esto ejecuta solo ese método. También puede seleccionar un archivo completo (pytest test_sample1.py) o filtrar por nombre con la opción -k.

Instala el complemento pytest-cov y luego ejecuta pytest –cov=tu_paquete. Este te mostrará el porcentaje de líneas ejecutadas por tus pruebas, y –cov-report=html generará un informe consultable que resalta las líneas no probadas.

El ámbito de una fixture controla la frecuencia de ejecución: función (predeterminado), clase, módulo, paquete o sesión. Configúralo con `@pytest.fixture(scope=”module”)`. Los ámbitos más amplios reutilizan configuraciones costosas, como una conexión a la base de datos, en varias pruebas.

Ejecuta `pytest -x` para detener la prueba inmediatamente después del primer fallo, o `pytest –maxfail=2` para detenerla tras un número determinado de fallos. Esto acorta el ciclo de retroalimentación al depurar un conjunto de pruebas defectuoso.

Pytest captura la salida estándar por defecto. Añade la opción -s (pytest -s) para desactivar la captura y mostrar las instrucciones print en tiempo real. La opción -v añade una salida detallada para cada prueba, que muestra el nombre de cada prueba y su resultado.

Los equipos de aprendizaje automático utilizan pytest para validar las canalizaciones de carga de datos, las transformaciones de características y las salidas de los modelos. Los fixtures proporcionan conjuntos de datos de muestra y la parametrización comprueba múltiples entradas, de modo que las partes inteligentes de un sistema se mantienen fiables a medida que cambia el código.

Sí. GitHub Copilot y los asistentes de IA con capacidad de generar funciones, datos de prueba y casos parametrizados para pytest a partir de una breve indicación o una función existente. RevRevise las afirmaciones generadas, ya que la IA puede pasar por alto casos extremos y juzgar erróneamente los valores esperados.

Resumir este post con: