Dónde suele empezar el testing de APIs en Python, y por qué está bien
No dejes que nadie te convenza de abandonar requests y pytest. Las pruebas son Python común y corriente, los fixtures se componen, parametrize cubre los valores límite con limpieza y cualquiera del equipo puede leerlo. Para una suite acotada alrededor de un servicio propio, esta sigue siendo una respuesta excelente.
Las cuatro cosas que se convierten en trabajo
Las sesiones. Un fixture de token funciona hasta que expira a mitad de la ejecución, y entonces terminas escribiendo lógica de renovación y almacenándola en caché entre workers.
Los valores capturados. Un identificador de una llamada alimenta la siguiente. Los fixtures lo resuelven hasta que el grafo se ensancha, y entonces el grafo de fixtures pasa a ser lo que mantienes.
El orden de ejecución. pytest no ordena por dependencias. Los equipos recurren a plugins de ordenamiento, y un único fallo temprano genera una pantalla llena de rojo que no tiene nada que ver con él.
La cuarta es la limpieza cuando hay paralelismo. En cuanto entra pytest-xdist en juego, borrar por patrón de nombre deja de ser seguro, y el teardown tiene que saber exactamente qué creó cada ejecución.
El costo real
Nada de esto es difícil por separado. Juntos se convierten en un framework interno: un conftest que nadie quiere tocar, un grafo de fixtures que solo una persona entiende y una suite que se pone en cuarentena en lugar de arreglarse cuando se pone en rojo. Ese desenlace es lo bastante común como para planificar teniéndolo en cuenta.
De qué se encarga una capa hecha para esto
Cuatro cosas deciden si una suite de API sobrevive su primer año, sea cual sea la herramienta que uses: sesiones que expiran, valores que solo existen en tiempo de ejecución, llamadas que dependen unas de otras y registros que nadie limpia. TestSprite las llama Auto-Authentication, Dynamic Variables, Dependency Chains y Auto-Cleanup, y la documentación de testing de APIs cubre la mecánica.
La cobertura también llega desde otro lugar. En lugar de los endpoints que alguien recordó, un plan generado a partir de una especificación o de un recorrido de descubrimiento sobre el servicio en ejecución incluye las rutas de error y los casos límite que nunca se escriben a mano.
Si quieres las pruebas en tu repositorio
Algunos equipos quieren que la suite viva en el repositorio y se revise como cualquier otro código, y es una preferencia legítima. El CLI admite pruebas de backend escritas en Python, con las dependencias declaradas por prueba y el teardown marcado como su propio caso, de modo que el grafo queda explícito en vez de quedar implícito en el anidamiento de fixtures. Los detalles están en el repositorio del CLI.
El conftest que se comió al equipo
Hay una forma reconocible en una suite de Python que ha crecido más de la cuenta, y vive en un solo archivo. El conftest empieza como un fixture de sesión y una URL base. Después un fixture de token, después una caché para no pedir el token en cada prueba, después un lock porque los workers de xdist competían por esa caché. Después factories, después un registro para que el teardown sepa qué eliminar, después marcadores de orden porque unas factories dependen de otras.
Cada paso es correcto por separado y el resultado son seiscientas líneas que entiende una sola persona. La señal aparece cuando alguien dice que una prueba está fallando y la primera pregunta es si cambió el conftest.
Vale la pena ponerle nombre porque la decisión de construirlo nunca se toma. Se acumula. Decidir pronto qué partes vas a mantener tú y cuáles preferirías no mantener sale más barato que descubrir la respuesta en el noveno mes.
Ejecútalas donde cambia el código
Una suite de Python que se ejecuta antes de los lanzamientos detecta las cosas tarde. Ejecutarla en cada pull request es el cambio que importa.
Hay dos caminos, y la elección tiene que ver en realidad con quién es dueño del pipeline. Conectar la GitHub App desde el panel no requiere ningún cambio en tu repositorio, porque reacciona al despliegue que tu build ya emite. Agregar un paso de GitHub Actions pone la verificación en el repositorio, donde se revisa como el resto del build.
De qué se encarga TestSprite para que tú no tengas que hacerlo
Las cuatro cosas que convierten una suite de pytest en infraestructura están resueltas como producto. Auto-Authentication obtiene y renueva las sesiones de cada entorno. Dynamic Variables lleva un identificador de una respuesta a la siguiente solicitud. Dependency Chains deduce el orden de ejecución a partir de lo que cada caso necesita y produce, de modo que un fallo omite sus dependientes en lugar de hacerlos fallar. Auto-Cleanup elimina exactamente lo que creó cada ejecución, que es lo que hace segura la ejecución en paralelo.
La cobertura también llega por otro camino. API Discovery enumera los endpoints que el servicio en ejecución expone realmente, y los planes generados incluyen las rutas de error y los valores límite que nunca se escriben al final de un sprint.
Lo que obtienes es una suite que nadie teme modificar, sin un conftest que solo entiende una persona. Conserva pytest para las pruebas unitarias y de lógica, donde es de verdad la mejor herramienta; de lo que se trata aquí es de dónde vive la amplitud de la cobertura.
¿Deberíamos dejar de usar pytest?
No. Consérvalo para las pruebas que tu equipo escribió a propósito, sobre todo las unitarias y las de nivel lógico. La discusión es sobre dónde vive la cobertura amplia de API.
¿Qué pasa con httpx y async?
Mejor ergonomía para la concurrencia, los mismos cuatro problemas. Las sesiones, los valores capturados, el orden y la limpieza son propiedades de probar un servicio con estado, no del cliente HTTP.
¿Cómo manejamos los datos de prueba?
Crea lo que cada prueba necesita y elimina exactamente eso, atado a la ejecución. Los datos precargados compartidos parecen cómodos y terminan siendo la razón por la que las pruebas solo pasan en un orden determinado.
¿Pueden convivir la cobertura generada y pytest?
Sí, y es el arreglo habitual. Cobertura generada para la amplitud, pytest para los casos que especificaste a propósito.
¿Sigue siendo Python una buena opción aquí?
Sí. El lenguaje no es la limitación. La limitación es cuánta infraestructura de pruebas quieres tener a tu cargo.
requests y pytest son la opción correcta hasta que aparece el estado.
El testing de APIs en Python empieza de maravilla y se convierte en un framework interno alrededor de las sesiones, los valores capturados, el orden y la limpieza. Conserva pytest para lo que especificaste a propósito y deja que una capa hecha para esto se encargue de la amplitud y de los cuatro problemas de estado.