Adoptar TDD para un complemento existente

El desarrollo basado en la prueba (TDD) es una filosofía del desarrollo de software que se basa en la redacción de pruebas antes de escribir una característica o remediación de errores. Esta es una gran diferencia en cómo piensas sobre el desarrollo. Me resulta muy difícil pasar a TDD, tanto porque es un modelo mental diferente como porque es difícil cambiar la forma en que aborda una base de código. Antes de TDD, escribí un código que debería funcionar, lo probé manualmente en mi navegador para ver por qué no funciona, lo reparé y luego escribí pruebas. Con TDD, escribo declaraciones de funciones y pruebas que describen cómo debería funcionar el código e identificar qué criterios me harían pensar que el código ha funcionado. Solo entonces funcionan. La definición de “obras” ya no es ambigua, tengo un estándar para juzgar y que se puede aplicar programáticamente. Al escribir mis criterios de prueba en el código, la persona que revisa el código puede abordar si los criterios de prueba son correctos o no. Esta última parte evita la declaración ambigua “funciona para mí” entre los miembros del equipo y la búsqueda para averiguar qué es diferente: el entorno de prueba o los criterios de prueba. Con el manual de control de calidad, a menos que documente cada paso de prueba, simplemente no tiene eso.
En este artículo, pasaré por el uso de ejemplos en mis formularios de caldera de complemento para usar Phunit para escribir aplicaciones para TDD. Este no es un artículo sobre cómo hacer pruebas en el desarrollo de WordPress. También escribí sobre pruebas unitarias de PHP, pruebas de integración de PHP, pruebas unitarias de JavaScript, integración de JavaScript para torque. Esta publicación se basa en mi experiencia en la adopción de TDD para nuestros formularios de caldera de complemento. Prefiero TDD y creo que es más rápido, especialmente en el desarrollo de JavaScript que las pruebas manuales con el navegador. Cuando se realice correctamente, haga que el código sea más fácil de mantener. Una introducción rápida a TDD si es nuevo en TDD, puede ser más fácil para usted pensar en ello como la primera prueba. Aquí están los pasos de una lista fácil de seguir:
Escriba suficiente de las funciones que necesita para describirlas en las pruebas.
Escribe pruebas fallidas.
Haga que pasen las pruebas.
Revisión de código.
Al usar TDD, debe hacer y impulsar ningún trabajo. Si empuja a un título de maestría o una rama de desarrollo antes de pasar las pruebas, significaría que cada cambio rompe la rama principal, lo cual es un problema. Por eso Git Flow tiene sentido. Abra una nueva subsidiaria, realice cambios incrementales y combine los cambios solo cuando las verificaciones automáticas, como pruebas, código de escaneo y una transición para revisar el código humano.
Hablemos de un ejemplo artificial, para que sea simple, luego veamos un ejemplo del mundo real. Supongamos que su requisito era crear un objeto para agregar dos números. En primer lugar, escribiría una función libre de cuerpo:
Luego agregaría dos pruebas para asegurarme de que se siguieran las reglas de matemáticas afirmadas: luego cambiaría mi función inicial, en una confirmación separada, para trabajar de manera efectiva:
La razón por la cual las pruebas fallidas se cometen antes de que funcione el código es por dos razones. En primer lugar, los compromisos deben hacer solo una cosa solo cuando sea posible. En segundo lugar, es posible que, después de aprobar las pruebas, usted o el código de la persona que examina el cambio para decidir que las pruebas fueron correctas, pero la implementación no lo fue. Si esto sucede, puede cancelar el comité con implementación sin perder las pruebas o hacer un GIT más sofisticado y luego a partir del final.
TDD paga este código posteriores pruebas de JavaScript en este momento. Pero si tiene una función bien probada, le permite repetirla de manera segura. Suponga que debe agregar un tercer argumento para redondear opcionalmente el resultado a un número especificado de decimales. Primero cambie la firma de la función:
Lo hice un argumento opcional para mantener la compatibilidad inversa. Para asegurarme de que mi suposición sea correcta, no cambiaré las pruebas existentes. Proban que se ha mantenido la retrocompatibilidad. Cambiar las pruebas existentes huele mal y es una señal de que sus pruebas son demasiado rígidas.
En su lugar, agregaría dos pruebas más:
Al implementar pruebas en cada etapa, aseguré que mis mejoras son mejoras reales y no causan nuevos defectos. Cuando necesita cambiar el código existente en el futuro, el tiempo que ha invertido en las pruebas. ¿Cuánta cobertura de prueba necesitas? Depende de lo que construyas. Las reglas más ortodoxas del TDD que puedo encontrar en el tío Bob: no se le permite escribir ningún código de producción a menos que se apruebe una prueba unitaria fallida.
No se le permite escribir una prueba unitaria más de lo que es suficiente para fallar, y las fallas son fallas.
No se le permite escribir más código de producción de lo que es suficiente para cruzar la prueba unitaria fallida.
Este es un estándar que es muy rígido y puede conducir fácilmente a pruebas que dificultan cambiar la base del código. Recuerde, el propósito es aumentar, no reducir la velocidad del desarrollo.
Kent C. Dobbs, un ingeniero de PayPal, que también es autor de una prueba de aplicaciones JavaScript, tiene una excelente publicación sobre este tema. Argumenta en esa publicación que “obtiene ganancias descendentes en las pruebas a medida que la cobertura aumenta en más del 70%”. No me gusta esta declaración, pero él tiene más experiencia que yo. Se da cuenta de que sus proyectos de código abierto tienen una cobertura del 100%, porque son “herramientas que son reutilizables en muchas situaciones diferentes (una ruptura podría conducir a un problema grave en muchos proyectos consumidores), lo que suena como una regla que se aplicaría. en un complemento de WordPress. También escribe que los proyectos HSS OSS son “relativamente fáciles de obtener una cobertura de código del 100%. Que no suena como muchos complementos de WordPress.
Personalmente, mi regla es más cobertura de la que tenemos actualmente. La falta de pruebas es una deuda técnica que disminuye más tarde. Si escribir pruebas ahora requiere más tiempo, vale la pena. Para un nuevo código, le obliga a escribir código utilizando modelos comprobables. Debe restaurar el código para que a veces sea un dolor comprobable. Las pruebas unitarias aisladas en WordPress no son simples. A menudo, las pruebas automáticas de la interfaz de usuario usando Cypress.io o Inspector Ghost me sirvieron mejor. Puedo cubrir mucha funcionalidad rápida, sin tener que preocuparme por el hecho de que el código no es realmente comprobable. Agregar una función TDD Me gustaría buscar un ejemplo de solicitud de extracción TDD a los formularios de caldera. En este caso, era una nueva función: agregar una configuración para el tamaño máximo de carga de archivo. Una parte del TDD que me gusta es que te obliga a descubrir qué nuevas funciones necesitas antes de escribirlas. No sé sobre ti, pero escribí muchos códigos que tardaron mucho tiempo en trabajar solo para darme cuenta de que no lo necesitaba. TDD me obliga a pensar en mis planes antes de seguir adelante. Aquí está la solicitud de extracción en GitHub si desea leerla: https://github.com/calderawp/caldera-forms/pull/2823
Debo señalar que este PR es extraño, porque tuvimos que combinar más ramas en progreso. La adopción de TDD está desordenada y afirma que sus leyes no son perfectamente respetadas.
Escribir las pruebas fallidas a veces es difícil hacer esto a la vez.Por ejemplo, en este caso, tuve que desarrollar algunos métodos utilitarios para leer la configuración del campo y verificar el tamaño del archivo y tuve que integrar esos métodos de utilidad en el código existente.Elegí hacer esto en dos pasos.I made the utilitarian methods work and test them and then I passed to use those new methods. My first commit: https://github.com/calderawp/caldera-forms/pull/2823/commits/d878e9d501af6ae92d72e45340440a185dea1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e To the code, I added Dos métodos utilitarios para una clase y no les di ningún cuerpo de función:
Esto está en esta comisión para el código que desarrolla.También hemos realizado pruebas que demuestran cómo deberían funcionar esas funciones:
Estas pruebas muestran cómo deberían funcionar los nuevos métodos. Los comentarios en línea explican por qué se hace cada declaración. Este proceso me obligó a pensar en cómo la configuración, que en este momento no tenía una interfaz de uso, debería estructurarse y cómo las usaré más tarde. Mi regla general es que un compromiso debe hacer solo una cosa. Este confirmación agrega los nuevos métodos y las pruebas fallidas. La palabra “y” de la oración anterior muestran que violé esta regla. Probablemente debería haber hecho dos comités. Más importante aún, quiero tener en cuenta que he pasado mucho tiempo trabajando en la lógica de lo que necesita ser probado y que hay muchas revisiones previas al control allí. Haciendo las pruebas para pasar en el pasado, cuando no usé TDD, debería probar esto agregando la opción UI, creando un formulario con esa opción, luego enviando el formulario con un archivo y veo si mi código funcionó como se esperaba como se esperaba. . El uso de XDebug para pasar por el código y examinar los resultados de las funciones ayuda mucho a este proceso, pero es muy lento. Además, una vez que funciona, no hay forma de saber si algo más se deshabilita más tarde. Es por eso que encuentro TDD más rápido, cuando sea posible, y ahorre tiempo y preocupaciones en el futuro. Sin embargo, ejecutar toda la serie de pruebas entre cada comité haría el proceso muy lento. Para las pruebas de JavaScript, uso la broma como corredor de prueba y se puede configurar fácilmente para ejecutar solo las pruebas que cambiaron.
Esto lleva a una estrategia en la que escribo pruebas fallidas, hago todas las pruebas relacionadas con la aprobación y luego les diga que ejecuten todas mis pruebas para asegurarse de que no suceda nada. Aquí hay un artículo sobre cómo hacer algo similar a Phapit. Mi solución personal es usar una anotación grupal “ahora” en mis documentos. En PhPunit, puede usar @Group para agrupar sus pruebas por función. Luego solo puede ejecutar pruebas en ese grupo con el grupo de bandera en la CLI phpunit. En los formularios de caldera tenemos un script compositor para ejecutar las pruebas de @Now. Con las pruebas en su lugar, podría comenzar a trabajar en mis dos nuevos métodos y solo ejecutar las dos pruebas y ver por qué cada prueba falla. En este proceso, vimos errores de PHP, advertencias y notificaciones, así como fallas en la prueba. Me molesté mucho en algún momento del código que debería haber funcionado y no tenía ninguna idea, pero al menos no estaba loco. También debo notar que la razón por la que escribí dos pruebas con múltiples declaraciones es que falla más rápido de esta manera. Si tuviera una declaración por prueba, como a menudo se recomienda y generalmente es una buena idea, habría visto alrededor de 10 fallas en la prueba. Es mucho más difícil de entender. Organizar una prueba con una declaración tras otra ayuda a resolver un problema a la vez. Las funciones reales que escribí parecen bastante simples:

Mis pruebas cubren algunas situaciones diferentes que son fáciles de pasar por alto.Por ejemplo, lo que sucede si la configuración no existe.La lógica condicional basada en el contenido de una matriz asociativa es difícil en el PHP, porque faltan las indicaciones, los valores pueden representarse con diferentes tipos escalares, lo que ocurre si todo el 1 o “1” o el “1” o el Las cadenas “verdaderas” se usan en lugar de boolean.¿Verdadero?
Ciertamente pensé que esto es simple, no necesito pruebas mientras trabajo en estos métodos. Además, mi primer intento no funcionó y lo sé solo porque mis pruebas fallaron y fallaron de una manera que me ayudó a ver por qué. Mover más allá del aislamiento, las pruebas hasta ahora han sido técnicamente pruebas de integración, porque el entorno requiere que WordPress funcione y no pensé que usar el maquillaje para pruebas unitarias valió la pena el dolor. El resto de las pruebas fueron principalmente pruebas de integración reales. Para los archivos de formularios de campos de caldera, tenemos un punto final separado para cargar el archivo. En este caso, no era necesario llegar al controlador de ese punto final, porque no mezclaba esta lógica en el controlador API. La responsabilidad del controlador API es la interacción entre la API de WordPress REST y una clase “cargada” separada que realiza la carga, utilizando los datos transmitidos desde la API REST. Esto significaba que tenía que hacer los cambios en “SubloadHandler”. Esa clase cambia. El cambio que se realizó fue necesario para imponer el límite del tamaño del archivo. La lógica de negocios estaba en otra parte. Solo tenía que asegurarme de que si le daba un archivo demasiado grande. Tenía que asegurarme de que con el archivo con el tamaño correcto funcione igual e hiciera una excepción cuando el archivo era demasiado grande. Aquí están las tres nuevas pruebas:
El primer testknowsFileSiSteolge () de prueba no hace todas las permutaciones de prueba que tenía para el método de utilidad que había creado anteriormente, porque ya sé que funciona. Estaba comprobando que la función funciona en este contexto. Segunda prueba – testExceWhenFileistoluge () – Asegura que el resultado de la prueba sea que se lanza una excepción. Tenga en cuenta que no he usado el modelo de try/captación. Usé ExpertException de PhPunit. Esta es la forma correcta de hacer esto de acuerdo con el manual de la funidad y hace que sea más fácil escribir que las afirmaciones dentro de una prueba/captura, pero significa que el código de prueba se ve menos que la forma en que alguien usaría el código, que huele un un poco malo para mí. Tercera prueba: testalowsfilesize (): asegúrese de que cuando se apruebe el archivo con el tamaño correcto, funciona como espera. Esta prueba no hace que nada sea súper específico. Lo agregué principalmente porque las pruebas existentes no tienen en cuenta estas configuraciones. Es una prueba de integración que fallará si una de las muchas cosas sale mal. Las pruebas con las que fallan indicarán más claramente cuál es el problema. Vale la pena la adopción de un enfoque basado en pruebas de desarrollo puede ayudar mucho, especialmente a medida que su equipo crece. Incluso para un desarrollador en solitario, obligarse a pensar en los cambios que debe hacer antes de hacer esos cambios tiene muchos beneficios. Además, el hecho de que las pruebas se implementen antes de la implementación significa que no pasa tiempo o poder cerebral probando o concebir modalidades de prueba.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

gkOVSBm5B8SgiXmo

Shopify vs WooCommerce – ¿Cuál es la mejor plataforma?(Comparación)

Shopify vs WooCommerce

Leave a Reply

Your email address will not be published. Required fields are marked *