Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. TDD
Code

Desarrollo práctico guiado por pruebas

by
Difficulty:IntermediateLength:MediumLanguages:

Spanish (Español) translation by Luis Chiabrera (you can also view the original English article)

¿Qué es el desarrollo guiado por pruebas?

El desarrollo dirigido por pruebas (DDP) simplemente significa que primero escribe sus pruebas. Establece las expectativas de código correcto por adelantado, incluso antes de haber escrito una sola línea de lógica de negocios. DDP no solo ayuda a asegurarse de que su código sea correcto, sino que también lo ayuda a escribir funciones más pequeñas, refactorizar su código sin romper la funcionalidad y entender mejor su problema.

En este artículo, presentaré algunos de los conceptos de DDP mediante la construcción de una pequeña utilidad. También cubriremos algunos de los escenarios prácticos en los que DDP simplificará su vida.

Construyendo un cliente HTTP con DDP

Lo que estaremos construyendo

Vamos a construir de forma incremental un cliente HTTP simple que abstrae varios verbos HTTP. Para suavizar los refactores, seguiremos las prácticas de DDP. Usaremos Jasmine, Sinon y Karma para las pruebas. Para comenzar, copie package.json, karma.conf.js y webpack.test.js del proyecto de muestra, o simplemente clone el proyecto de muestra desde el repositorio de GitHub.

Es útil si comprende cómo funciona la nueva API Fetch, pero los ejemplos deberían ser fáciles de seguir. Para los no iniciados, la API Fetch es una mejor alternativa a XMLHttpRequest. Simplifica las interacciones de red y funciona bien con Promesas.

Una envoltura sobre GET

Primero, cree un archivo vacío en src / http.js y un archivo de prueba adjunto en src / __ tests __ / http-test.js.

Vamos a configurar un entorno de prueba para este servicio.

Aquí utilizamos tanto a Jasmine como a Sinon: Jasmine para definir los escenarios de prueba y Sinon para afirmar y espiar objetos. (Jasmine tiene su propia manera de espiar y aplastar las pruebas, pero me gusta más la API de Sinon).

El código anterior se explica por sí mismo. Antes de cada ejecución de prueba, secuestramos la llamada a la API Fetch, ya que no hay un servidor disponible, y devolvemos un objeto de promesa falsa. El objetivo aquí es probar la unidad si se llama a la API Fetch con los parámetros correctos y ver si la envoltura es capaz de manejar cualquier error de red correctamente.

Comencemos con un caso de prueba fallido:

Comience su corredor de prueba llamando a karma start. Las pruebas obviamente fallarán ahora, ya que no hay un método GET en http. Vamos a rectificar eso.

Si ejecuta sus pruebas ahora, verá una respuesta fallida que dice Expected [object Response] to equal Object({ }). La respuesta es un objeto Stream. Los objetos de secuencia, como su nombre indica, son cada uno una secuencia de datos. Para obtener los datos de un flujo, primero debe leer el flujo, usando algunos de sus métodos de ayuda. Por ahora, podemos asumir que la transmisión será JSON y deserializarla llamando a response.json ().

Nuestra suite de pruebas debería ser verde ahora.

Agregando Parámetros de Consulta

Hasta ahora, el método get solo realiza una llamada simple sin ningún parámetro de consulta. Escribamos una prueba fallida para ver cómo debería funcionar con los parámetros de consulta. Si pasamos {users: [1, 2], limit: 50, isDetailed: false} como parámetros de consulta, nuestro cliente HTTP debe hacer una llamada de red a / api / v1 / users /? Users = 1 & users = 2 & limit = 50 & isDetailed = false

Ahora que tenemos nuestra configuración de prueba, extendamos nuestro método get para manejar los parámetros de consulta.

Si los parámetros están presentes, construimos una cadena de consulta y la agregamos a la URL.

Aquí he usado la biblioteca de cadenas de consulta: es una pequeña biblioteca de ayuda que ayuda a manejar varios escenarios de parámetros de consulta.

Manejo de mutaciones

GET es quizás el método HTTP más simple de implementar. GET es idempotente, y no debe usarse para ninguna mutación. La POST normalmente está destinada a actualizar algunos registros en el servidor. Esto significa que las solicitudes POST necesitan algunas barreras de seguridad en su lugar de manera predeterminada, como un token CSRF. Más sobre eso en la siguiente sección.

Comencemos por construir una prueba para una solicitud POST básica:

La firma para el POST es muy similar a GET. Toma una propiedad de options, donde puede definir los encabezados, cuerpo y, lo más importante, el method. El método describe el verbo HTTP, en este caso, "post".

Por ahora, supongamos que el tipo de contenido es JSON y comencemos nuestra implementación de la solicitud POST.

En este punto, nuestro método post es muy primitivo. No soporta nada más que una solicitud JSON.

Tipos de contenido alternativos y tokens CSRF

Permitámosle a la persona que llama que decida el tipo de contenido y lancemos el token CSRF a la refriega. Dependiendo de sus requisitos, puede hacer que CSRF sea opcional. En nuestro caso de uso, asumiremos que esta es una función de aceptación y dejaremos que la persona que llama determine si necesita configurar un token CSRF en el encabezado.

Para hacer esto, comience pasando un objeto de opciones como el tercer parámetro a nuestro método.

Cuando suministramos options con {contentType: http.HTTP_HEADER_TYPES.text, includeCsrf: true, debe establecer el encabezado de contenido y los encabezados de CSRF en consecuencia. Vamos a actualizar la función de post para soportar estas nuevas opciones.

Tenga en cuenta que obtener el token CSRF es un detalle de implementación. Por lo general, es parte de la cookie de sesión y puede extraerla desde allí. No lo cubriré más en este artículo.

Tu suite de pruebas debería estar feliz ahora.

Formas de codificación

Nuestro método post está tomando forma ahora, pero aún es trivial al enviar el cuerpo. Tendrás que masajear tus datos de manera diferente para cada tipo de contenido. Cuando se trata de formularios, debemos codificar los datos como una cadena antes de enviarlos a través del cable.

Extraigamos un pequeño método de ayuda para hacer este trabajo pesado. Basado en el contentType, procesa los datos de manera diferente.

¡Mira eso! Nuestras pruebas siguen pasando incluso después de refactorizar un componente central.

Manejo de solicitudes PATCH

Otro verbo HTTP comúnmente usado es PATCH. Ahora, PATCH es una llamada mutativa, lo que significa que su firma de estas dos acciones es muy similar. La única diferencia está en el verbo HTTP. Podemos reutilizar todas las pruebas que escribimos para POST, con un simple ajuste.

De manera similar, podemos reutilizar el método post actual al hacer que el verbo sea configurable y cambiar el nombre del método para reflejar algo genérico.

Ahora que todas nuestras pruebas POST están pasando, todo lo que queda es agregar otro método para el patch.

Simple, ¿verdad? Como ejercicio, intente agregar una solicitud PUT o DELETE por su cuenta. Si estás atascado, no dudes en consultar el repositorio.

¿Cuándo a TDD?

La comunidad está dividida en esto. Algunos programadores ejecutan y ocultan el momento en que escuchan la palabra DDP, mientras que otros viven con ella. Puede lograr algunos de los efectos beneficiosos de DDP simplemente teniendo un buen conjunto de pruebas. No hay una respuesta correcta aquí. Se trata de cuán cómodos están usted y su equipo con su enfoque.

Como regla general, uso DDP para problemas complejos y no estructurados sobre los que necesito más claridad. Al evaluar un enfoque o comparar varios enfoques, me resulta útil definir la declaración del problema y los límites desde el principio. Ayuda a cristalizar los requisitos y los casos extremos que su función necesita manejar. Si el número de casos es demasiado alto, sugiere que su programa puede estar haciendo demasiadas cosas y quizás es hora de dividirlo en unidades más pequeñas. Si los requisitos son sencillos, me salto DDP y agrego las pruebas más tarde.

Terminando

Hay mucho ruido en este tema, y es fácil perderse. Si puedo dejarte con algunos consejos de despedida: no te preocupes demasiado por el DDP en sí, sino enfócate en los principios subyacentes. Se trata de escribir un código limpio, fácil de entender y fácil de mantener. DDP es una habilidad útil en el cinturón de herramientas de un programador. Con el tiempo, desarrollará una intuición sobre cuándo aplicar esto.

Gracias por leer, y háganos saber sus pensamientos en la sección de comentarios.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.