Probar su código es molesto, pero el impacto de no hacerlo puede ser órdenes de magnitud más molestos. En este artículo, usaremos el desarrollo guiado por pruebas para escribir y probar nuestro código de manera más efectiva.
Desde el comienzo de la era de las computadoras, los programadores y los insectos han luchado por la supremacía. Es una ocurrencia inevitable. Incluso los mejores programadores caen presa de estas anomalías. Ningún código es seguro. Es por eso que hacemos pruebas. Los programadores, al menos los sanos, prueban su código ejecutándolo en máquinas de desarrollo para asegurarse de que hace lo que se supone que debe hacer.
Desarrollo guiado por pruebas es una técnica de programación que requiere que usted escriba código real y código de prueba automatizado simultáneamente. Esto asegura que usted prueba su código y le permite volver a probar su código rápida y fácilmente, ya que es automático.
El desarrollo guiado por pruebas, o TDD, como lo llamaremos a partir de ahora, gira en torno a un ciclo de desarrollo iterativo corto que dice algo como esto:
¿Alguna vez ha omitido intencionalmente probar un programa porque:
La mayoría de las veces, no sucede nada, y usted mueve con éxito su código a producción sin ningún problema. Pero a veces, después de pasar a la producción, todo va mal. Estás atascado arreglando cien agujeros en un barco que se hunde, con más apareciendo cada minuto. Tú lo haces no quiero encontrarte en esta situación.
TDD estaba destinado a eliminar nuestras excusas. Cuando un programa se ha desarrollado utilizando TDD, nos permite realizar cambios y realizar pruebas de forma rápida y eficiente. Todo lo que necesitamos hacer es ejecutar las pruebas automatizadas, y listo! Si pasa todas las pruebas automatizadas, entonces estamos bien, si no, entonces solo significa que rompimos algo con los cambios. Al saber qué partes exactas de la prueba fallaron, también nos permite identificar fácilmente en qué parte de los cambios se rompió, lo que facilita la solución de errores..
Hay una multitud de marcos de prueba automatizados de PHP que podemos usar. Uno de los marcos de prueba más utilizados es PHPUnit..
PHPUnit es un excelente marco de prueba, que puede integrarse fácilmente en sus propios proyectos u otros proyectos construidos sobre los marcos de PHP populares.
Sin embargo, para nuestros propósitos, no necesitaremos la multitud de funciones que ofrece PHPUnit. En su lugar, optaremos por crear nuestras pruebas utilizando un marco de prueba mucho más sencillo, llamado SimpleTest.
En los siguientes pasos, supongamos que estamos desarrollando una aplicación de libro de visitas donde cualquier usuario puede agregar y ver las entradas del libro de visitas. Supongamos que el marcado se ha completado, y que simplemente estamos haciendo una clase que contiene el lógica de aplicación del libro de visitas, que es donde la aplicación inserta y lee en la base de datos. La parte de lectura de esta clase es lo que vamos a desarrollar y probar..
Este es posiblemente el paso más fácil de todos. Incluso este tipo podría hacerlo:
Descargue SimpleTest aquí y extraiga a la carpeta de su elección, preferiblemente la carpeta donde va a desarrollar su código, o su ruta de inclusión de PHP para un fácil acceso.
Para este tutorial, he configurado la carpeta así:
Index.php ejecutará guestbook.php, invocará el método de visualización y mostrará las entradas. Dentro de la carpeta de clases es donde colocaremos la clase guestbook.php, y la carpeta de prueba es donde ubicaremos la biblioteca más simple.
El segundo paso, que en realidad es el más importante, es comenzar a crear las pruebas. Para esto, realmente necesita planificar y pensar qué hará su función, qué entradas posibles obtendrá y las salidas correspondientes que enviará. Este paso se asemeja a jugar un juego de ajedrez: necesitas saber todo sobre tu oponente (el programa), incluidas todas sus debilidades (posibles errores) y fortalezas (qué sucede si se ejecuta con éxito).
Así que para nuestra aplicación de libro de visitas, vamos a establecer los esquemas:
Array ([0] => Array (['name'] = "Bob" ['message'] = "Hola, soy Bob.") [1] => Array (['name'] = "Tom" ['mensaje'] = "Hola, soy Tom."))
Ahora, podemos escribir nuestra primera prueba. Empecemos creando un archivo llamado guestbook_test.php dentro de la carpeta de prueba.
Entonces, vamos a convertir lo que hemos determinado en el paso dos,.
agregar ("Bob", "Hola, soy Bob"); $ guestbook-> add ("Tom", "Hola, soy Tom."); $ entries = $ guestbook-> viewAll (); $ count_is_greater_than_zero = (count ($ entries)> 0); $ this-> assertTrue ($ count_is_greater_than_zero); $ this-> assertIsA ($ entries, 'array'); foreach ($ entries como $ entry) $ this-> assertIsA ($ entry, 'array'); $ this-> assertTrue (isset ($ entry ['name'])); $ this-> assertTrue (isset ($ entry ['message'])); function testViewGuestbookWithNoEntries () $ guestbook = new Guestbook (); $ guestbook-> deleteAll (); // Borre todas las entradas primero para que sepamos que es una tabla vacía $ entries = $ guestbook-> viewAll (); $ this-> assertEqual ($ entries, array ());Las afirmaciones aseguran que cierta cosa es lo que se supone que es, básicamente, asegura que lo que se devuelve es lo que usted espera que regrese. Por ejemplo, si se supone que una función devuelve true si tiene éxito, entonces en nuestra prueba, deberíamos afirmar que el valor de retorno es igual a verdadero.
Como puede ver aquí, probamos la visualización del libro de visitas con entradas y sin ellas. Verificamos si estos dos escenarios pasan nuestros criterios del paso dos. Probablemente también haya notado que cada una de nuestras funciones de prueba comienza con la palabra 'prueba'. Hicimos esto porque, cuando SimpleTest ejecuta esta clase, buscará todas las funciones que comienzan con la palabra "prueba" y la ejecutan.
En nuestra clase de prueba, también hemos usado algunos métodos de afirmación, como assertTrue, assertIsA y assertEquals. La función assertTrue verifica si un valor es verdadero o no. AssertIsA verifica si una variable es de un determinado tipo o clase. Y, por último, assertEquals verifica si una variable es totalmente igual a un cierto valor.
Hay otros métodos de afirmación proporcionados por SimpleTest, que son:
assertTrue ($ x) | Falla si $ x es falso |
assertFalse ($ x) | Falla si $ x es verdadero |
assertNull ($ x) | Fallo si se establece $ x |
assertNotNull ($ x) | Fallo si $ x no se establece |
assertIsA ($ x, $ t) | Falla si $ x no es la clase o el tipo $ t |
assertNotA ($ x, $ t) | Falla si $ x es de la clase o tipo $ t |
assertEqual ($ x, $ y) | Falla si $ x == $ y es falso |
assertNotEqual ($ x, $ y) | Falla si $ x == $ y es verdadero |
assertWithinMargin ($ x, $ y, $ m) | Fallo si abs ($ x - $ y) < $m is false |
assertOutsideMargin ($ x, $ y, $ m) | Fallo si abs ($ x - $ y) < $m is true |
assertIdentical ($ x, $ y) | Fallo si $ x == $ y es falso o una falta de coincidencia de tipo |
assertNotIdentical ($ x, $ y) | Fallo si $ x == $ y es verdadero y los tipos coinciden |
assertReference ($ x, $ y) | Falla a menos que $ x y $ y sean la misma variable |
assertClone ($ x, $ y) | Falla a menos que $ x y $ y sean copias idénticas |
assertPattern ($ p, $ x) | Falla a menos que la expresión regular $ p coincida con $ x |
assertNoPattern ($ p, $ x) | Falla si la expresión regular $ p coincide con $ x |
expectError ($ x) | Traga cualquier error próximo coincidente |
afirmar ($ e) | Fallo en el objeto de expectativa fallida $ e |
Lista de métodos de aserción cortesía de http://www.simpletest.org/en/unit_test_documentation.html
Una vez que haya terminado de escribir el código, debe ejecutar la prueba. La primera vez que ejecutas la prueba, DEBE FALLAR. Si no lo hace, entonces significa que tu prueba no prueba nada.
Para ejecutar su prueba, simplemente ejecute guestbook_test.php en tu navegador Deberías ver esto primero:
Esto sucedió porque todavía no hemos creado nuestra clase de libro de visitas. Para hacerlo, crea guestbook.php dentro de tu carpeta de clases. La clase debe contener los métodos que planeamos utilizar, pero al principio no debe contener nada. Recuerda, primero estamos escribiendo las pruebas. antes de escribiendo cualquier código.
Cuando vuelva a ejecutar la prueba, debería verse algo como esto:
Como podemos ver aquí, nuestra prueba ahora está ganando al fallar. Esto significa que nuestra prueba ahora está lista para ser "contestada".
Imagen cortesía de http://www.gamercastnetwork.com/forums
Paso 5. Contesta tu prueba escribiendo un código
En algún momento, todos nos hemos sentido así cuando estamos programando.
Imagen cortesía de http://fermentation.typepad.com/fermentationAhora que tenemos una prueba automatizada de trabajo, podemos comenzar a escribir código. Abre tu guestbook.php Clase y empieza a crear la respuesta a tu prueba..
'Kirk', 'mensaje' => 'Hola, soy Kirk'. ), array ('name' => 'Ted', 'message' => 'Hi, I \' m Ted. ')); public function viewAll () // Aquí, deberíamos recuperar todos los registros de la base de datos. // Esto se simula devolviendo $ _entries array return self :: $ _ entries; función pública add ($ nombre, $ mensaje) // Aquí, simulamos la inserción en la base de datos agregando un nuevo registro en la matriz $ _entries // Esta es la forma correcta de hacerlo: self :: $ _ entries [] = array ('nombre' => $ nombre, 'mensaje' => $ mensaje); self :: $ _ entries [] = array ('notname' => $ name, 'notmessage' => $ message); // Vaya, hay un error aquí en algún lugar devuelto true; public function deleteAll () // Acabamos de configurar la matriz $ _entries para simular self :: $ _ entries = array (); devuelve verdaderoEsta clase guestbook.php tiene algunos errores a propósito, por lo que podemos ver cómo se ve si falla nuestra prueba..
Una vez que ejecutamos nuestra prueba, deberíamos ver algo como esto:
El resultado de la prueba nos muestra en qué prueba y en qué afirmación falló nuestro código. A partir de esto, podemos señalar fácilmente que la línea 16 y 17 fue la afirmación de que arrojó el error.
assertTrue (isset ($ entry ['name'])); $ this-> assertTrue (isset ($ entry ['message'])) ;?Esto claramente nos dice que la matriz de entrada devuelta no tenía la clave de matriz correcta. Sobre esta base, sabremos fácilmente qué parte de nuestro código salió mal.
$ nombre, 'mensaje' => $ mensaje); //¡fijo! devuelve verdadero ?Ahora, cuando volvamos a ejecutar nuestra prueba, debería mostrarnos:
Paso 6. Refactoriza y refina tu código
Imágenes cortesía de http://www.osborneink.com y http://phuketnews.phuketindex.comDado que el código que estamos probando aquí es bastante simple, nuestras pruebas y corrección de errores no duraron mucho. Pero si se tratara de una aplicación más compleja, tendría que realizar varios cambios en su código, hacerlo más limpio para que sea más fácil de mantener y muchas otras cosas. El problema con esto, sin embargo, es que el cambio generalmente introduce errores adicionales. Aquí es donde entra nuestra prueba automatizada; una vez que hacemos cambios, simplemente podemos ejecutar la prueba nuevamente. Si aún pasa, significa que no rompimos nada. Si falla, sabemos que cometimos un error. También nos informa dónde está el problema y, con suerte, cómo podremos solucionarlo..
Paso 7. Enjuague y repita
Imagen cortesía de http://www.philstockworld.comEventualmente, cuando su programa requiera una nueva funcionalidad, deberá escribir nuevas pruebas. ¡Eso es fácil! Enjuague y repita los procedimientos del paso dos (ya que sus archivos de SimpleTest ya deberían estar configurados), y comience el ciclo nuevamente..
Conclusión
Hay muchos más artículos de desarrollo guiados por pruebas en profundidad por ahí, e incluso más funcionalidad para SimpleTest que lo que se mostró en este artículo, cosas como objetos simulados, talones, que facilitan la creación de pruebas. Si desea leer más, la página de desarrollo guiada por prueba de Wikipedia debería ponerlo en el camino correcto. Si está interesado en utilizar SimpleTest como marco de prueba, explore la documentación en línea y asegúrese de revisar sus otras características..
Las pruebas son una parte integral del ciclo de desarrollo, sin embargo, a menudo es lo primero que se debe recortar cuando los plazos son inminentes. Con suerte, después de leer este artículo, apreciará lo útil que es invertir en desarrollo basado en pruebas..
¿Qué piensas sobre el desarrollo guiado por pruebas? ¿Es algo que te interesa implementar o crees que es una pérdida de tiempo? Házmelo saber en los comentarios!