Gooosh I wish I had the capability to slow down audio
I really want to slow down this song without screwing pitches. It would be glorious and a godsend. But no. I cannot.

seen from Japan

seen from Singapore

seen from Malaysia
seen from Russia
seen from China

seen from United States
seen from China
seen from United States
seen from Malaysia
seen from Japan
seen from United States

seen from Russia

seen from United States
seen from Chile
seen from United States

seen from United States

seen from Malaysia

seen from Japan
seen from China

seen from United States
Gooosh I wish I had the capability to slow down audio
I really want to slow down this song without screwing pitches. It would be glorious and a godsend. But no. I cannot.
Tutorial Symfony - Jobeet dia 8 - Pruebas unitarias
Tests in symfony
A veces cuando añadimos una funcionalidad, refactorizamos una clase o simplemente hacemos un cambio, no tenemos ni puta idea si el programa se va a cascar. Symfony te permite realizar una serie de pruebas automatizadas que permiten mantener la ingridad del código, se dividen en:
Pruebas unitarias: prueban que cada método o función devuelve los resultados correctos, es independiente y prueba una cosa cada vez.
Pruebas funcionales: prueban el funcionamiento en conjunto, las veremos en el dia 9.
Todas estas pruebas se almacenan en /test/unit y /test/functional respectivamente.
Unit Tests
No hay que hacer pruebas a todo el software, lo mejor es empezar con los puntos críticos o donde encontremos bugs, nos permitirán mantener el código en una versión estable.
Para ello SF tiene un framework llamado lime para hacer pruebas, también puedes usar PHPunit.
The lime Testing Framework
Todas las pruebas de test empiezan igual, el número en lime_test() indica el número de pruebas que se van a realizar.
require_once dirname(__FILE__).'/../bootstrap/unit.php'; $t = new lime_test(1);
auque podríamos depurar todo con un método ok(), nos devuelve TRUE si lo cumple o FALSE en caso contrario, SF tiene un conjunto de métodos que nos ayuda a depurar o filtrar.
ok($test) Test a una condición y la pasa si es TRUE
is($value1, $value2) Compara dos valores y pasa si son iguales
isnt($value1, $value2) Compara dos valores y pasa si NO son iguales
like($string, $regexp) Prueba un string si cumple una expresión regular
unlike($string, $regexp) Prueba un string si NO cumple una expresión regular
is_deeply($array1, $array2) Compara dos arrays, pasa si son iguales
fail() Siempre falla, útil para test de excepciones
pass() Siempre pasa, útil para test de excepciones
skip($msg, $nb_tests) Cuenta el número de test, útil para condicionales
todo() Para test que todavía no están hechos ¿?
Por último hay un test llamado comment($msg) que muestra un mensaje pero no hace ningún test.
Running Unit Tests
Empezamos a crear el primer fichero de test, la nomenclatura es /test/unit/Nombre_CaseTest. CopyPaste y lo ejecutamos mediante:
$ php symfony test:unit Jobeet
Testing slugify
Durante el día 5 hemos creado unos parseadores que llamamos slugify para hacer las beautyURLs, su trabajo era:
pasaban todo a minúsculas
transformaban espacios y caracteres no-ASCII en guiones "-"
Seguimos los pasos, recuerda PRUEBA UNA ÚNICA COSA EN CADA TEST. Vamos a usar el método is() para comprobar distintas entradas y ver que formatea correctamente, todas las pruebas permiten un último parámetro de comentarios que nos sirve para documentar las pruebas.
Si queremos ser más papistas que el Papa, podemos bajarnos Xdebug para que nos diga si se han testeado todas las líneas del código, OJO los casos extremos los debemos crear nosotros, esto sólo cuenta líneas.
Yo paso por el momento... ;)
Adding Tests for new Features
Slug tiene algunos errores, por ejemplo si viene una cadena vacía, devuelve vacío y eso es caca cuando vayamos a crear una URL. Creamos primero el test y luego implementamos la funcionalidad, esta metodología se llama TDD.
Ahora añadimos la funcionalidad en la clase Jobeet y todo debe ir bien.
Adding Tests because of a Bug
Vamos a seguir mejorando el código, en este caso si un campo tiene sólo caracteres noASCII termina devolviendo la cadena vacía, creamos la prueba y modificamos el código.
Las vocales con acento también las cambia a guiones, utilizaremos la función iconv() este caso llamado "transliteration". No me queda muy claro donde tiene esta librería instalada pero funciona.
Doctrine Unit Tests
Es recomendable crear una bd dedicada para los test, SF puede utilizar una base de datos distinta para cada entorno por lo que crearemos una con el siguiente comando.
Database Configuration
$ php symfony configure:database --name=doctrine --class=sfDoctrineDatabase --env=test "mysql:host=localhost;dbname=jobeet_test" root PASSWORD
Puedes ver en /config/databases.yml como ha creado todo lo que necesita, pero todavía no tenemos ni la base de datos ni las tablas creadas. Para ello entro en phpmyadmin y creo jobeet_test. Luego cargo las tablas de desarrollo.
$ php symfony doctrine:insert-sql --env=test
La mayoría de los ficheros de configuración de la aplicación que están en YAML (databases, app, view, settings) permiten configurar los distintos entornos o utilizar el mismo con la clave all.
Test Data
Lo que hago a continuación es copiar los datos por defecto de /data/fixures a /text/fixures para que cuando haga el loadData(), más tarde pueda encontrarlos.
Testing JobeetJob
Ahora vamos a crear las pruebas unitarias en /test/bootstrap/Doctrine.php, en este archivo definiremos la cabecera muy parecida a la anterior, la conexión a la base de datos y la funcionalidad que vamos a testear.
Doctrine sólo conecta a la base de datos hasta que tiene querys para ejecutar, así que por el momento no podemos probar nada. Copiamos los archivos de /data/fixtures a /test/fixtures, ya que el método loadData() es capaz de coger archivos, directorios y todo su contenido.
CopyPaste del archivo creado y lo ejecutamos desde consola con
php test/bootstrap/Doctrine.php
Ahora hemos creado las tuplas dentro de las tablas, que estaban vacías. Si tienes un error porque no puede instanciar los objetos, puede ser que las tablas estén vacías. Nos queda añadir la funcionalidad a las pruebas que queremos realizar antes de ejecutarlas con:
./symfony test:unit JobeetJob
Recuerda que no hay que poner Test al final.
Test other Doctrine Classes
Puedo hacerlo para las otras clases pero por el momento no lo veo prioritario.
Unit Tests Harness
Podemos hacer un symfony test:unit que nos da la salida de todos los test de la aplicación juntos, muy profesional
Final Thoughts
Los test parecen una gilipollez para una primera versión, cuando un software empieza a coger cuerpo y necesitas sacar nuevas funcionalidades y módulos, los necesitarás para no estar probando lo mismo todo el tiempo. Recuerda que los ordenadores se crearon para automatizar tareas, no para dar más.