Pruebas unitarias en Python: unittest

unittest, también conocido como PyUnit, pertenece a ese grupo de herramientas conocido como zUnit. Un conjunto de frameworks con base en SUnit para Smalltalk, de Kent Beck.
El uso de unittest es sencillo, cuando menos al tener práctica. Para cada uno de los grupos de pruebas, debemos de crear una clase que herede de unittest.TestCase, y desde ahí, ir creando métodos que comiencen con test. Cada uno de estos métodos será cada una de las pruebas que realizaremos. El resultado de cada una puede ser:
  • OK, prueba exitosa.
  • FAIL, la prueba ha fallado y se lanza una excepción AssertionError.
  • ERROR, la prueba ha fallado, pero se lanza una excepción distinta de AssertionError.
Aunque como en programación Python, se puede hacer uso de clausulas if, o emplear try/except, la clase TestCase tiene ya implementados una serie de métodos que facilitan las comprobaciones.

Métodos de comprobación

  • assertAlmostEqual(first, second, places=7, msg=None)
    Comprueba que los objetos pasados sean iguales hasta el decimal pasado como parámetro.
  • assertEqual(first, second, msg=None)
    Comprueba que los objetos pasados como parámetros sean iguales.
  • assertFalse(expr, msg=None)
    Comprueba que la expresión sea falsa.
  • assertNotAlmostEqual(first, second, places=7, msg=None)
    Comprueba que los objetos pasados como parámetros no sean iguales hasta el decimal pasado como parámetro.
  • assertNotEqual(first, second, msg=None)
    Comprueba que los objetos pasados como parámetros no sean iguales.
  • assertRaises(excClass, callableObj, *args, **kwargs)
    Comprueba que al llamar al objeto callableObj con los parámetros definidos en *args y **kwargs se lanza una excepción de tipo excClass.
  • assertTrue(expr, msg=None)
    Comprueba que la expresión sea cierta.
  • assert_(expr, msg=None)
    Comprueba que la expresión sea cierta.
  • fail(msg=None)
    Falla inmediatamente.
  • failIf(expr, msg=aquí ponemos lo que queramos desplegar)
    Falla si la expresión es cierta.
  • failIfAlmostEqual(first, second, places=7, msg=None)
    Falla si los objetos pasados como parámetros son iguales hasta el decimal pasado como parámetro.
  • failIfEqual(first, second, msg=None)
    Falla si los objetos pasados como parámetros son iguales.
  • failUnless(expr, msg=None)
    Falla a menos que la expresión sea cierta.
  • failUnlessAlmostEqual(first, second, places=7, msg=None)
    Falla a menos que los objetos pasados como parámetros sean iguales hasta el decimal pasado como parámetro.
  • failUnlessEqual(first, second, msg=None)
    Falla a menos que los objetos pasados como parámetros sean iguales.
  • failUnlessRaises(excClass, callableObj, *args, **kwargs)
    Falla a menos que al llamar al objeto callableObj con los parámetros definidos por *args y **kwargs se lance una excepción de tipo excClass.

Referencias

Leer más

Bash: Control de errores y debug

Recientemente hablamos acerca de las diferencias de usar /bin/bash o /usr/bin/env bash. No suele ser algo muy habitual, pero puede resultar de gran ayuda.
Hoy vamos a ver otro de esos pequeños trucos de bash, pero que puede resultar de gran ayuda. Estamos hablando del control de errores y de habilitar el modo debug.
Como suele ser habitual es los script en bash, tras inicializar el entorno, se suele poner el comando 'set -e', abreviatura de 'set -o errexit'.
#!/usr/bin/env bash
set -e

# Código bash a ejecutar...
En caso de que durante la ejecución del script aparezca algún error, inmediatamente detendrá la ejecución del script.

El método antes comentando suele ser útil para scripts de producción, donde se presupone que no van a existir errores y por lo tanto no es necesario saber exactamente lo que pasa. Sin embargo, cuando estamos escribiendo código, sí puede resultar muy útil tener habilitado el modo debug. Para eso, 'set -x' es la solución.
#!/usr/bin/env bash
set -x

# Código bash a ejecutar...

Nota: 'set -x' en el script es lo mismo que 'bash -x tu_script'.
Leer más

MySQL, rotado de slow logs

Hace un tiempo publicamos una entrada acerca de cómo activar el log de Slow Query's para MySQL. Esta práctica suele ser bastante habitual y recomendada. Si una query tarda mucho en ejecutarse puede comprometer todo el rendimiento del sistema. Así que mejor saber cual es, para poder solucionarla (si es posible).
El detalle que nos trae a cuenta es que este log, al final es un fichero de texto con muchas entradas, pero que crece de forma indefinida y cada vez ocupa más o más espacio. Para evitar que crezca de forma descontrolada, lo que debemos hacer es rotarlo. Para hacer esta tarea, los sistemas GNU/Linux emplean logrotate.
Logrotate tiene dos técnicas de rotación,
  • copytruncate, copia el fichero a uno nuevo y luego lo trunca.
  • no copytruncate, emplea la función rename del sistema para mover el fichero a uno nuevo. Luego el daemon que escribe necesita recibir la señal de reopen.
El problema que tenemos es que truncar el fichero de logs de MySQL puede hacer que éste se bloquee y cambiar el nombre del fichero y reiniciar el servicio, no siempre es posible, ya que dejaríamos el sistema por un tiempo sin servicio. Puede no ser mucho, pero suficiente. Para solucionar este problema, desde el blog de Percona ofrecen una solución. Lo primero es crear el fichero de configuración en logrotate (mysql-slow).
/var/log/mysql/slow_query.log {
   nocompress
   create 660 mysql mysql
   size 1G
   dateext
   missingok
   notifempty
   sharedscripts
   postrotate
      mysql -u logrotate -ppasswd -e 'select @@global.long_query_time into @lqt_save; set global long_query_time=2000; select sleep(2); FLUSH LOGS; select sleep(2); set global long_query_time=@lqt_save;'
   endscript
   rotate 150
A diferencia del código original, nosotros vamos a configurar un usuario que tenga acceso restringido al servicio MySQL para poder hacer las operaciones que necesita. El usuario será logrotate,
mysql> CREATE USER 'logrotate'@'localhost' IDENTIFIED BY 'passwd';
mysql> GRANT select,file,super,reload ON *.* TO 'logrotate'@'localhost';
La idea de crear este usuario es para evitar problemas de seguridad de acceder con root o tener el sistema sin contraseña para localhost.
Con el usuario ya creado, probamos si el fichero de configuración de logrotate funciona. Para ello,
shell> logrotate -vf /etc/logrotate.d/mysql-slow
Si no hay fallos, el fichero de logs se rotará de forma automatizada.
Leer más

/bin/bash vs. /usr/bin/env bash

Cuando estamos programando un script en bash siempre solemos inicializarlo con la línea que indica que es eso, un script en bash. Esta línea a mayores nos indica el path del intérprete. Por norma general, suele ser siempre /bin/bash/usr/bin/bash. Este "o" es el que puede causarnos algunos problemas. Para evitarlo, podemos emplear el siguiente truco: llamar a la función de enviroment. Es decir, pasamos de comenzar el script típico,
#!/bin/bash

# Código bash a ejecutar...
A usar las variables de entorno, para que sea ésta la que localice el path exacto donde está bash.
#!/usr/bin/env bash

# Código bash a ejecutar...
Con esto lo que conseguimos es hacer el script más flexible y adaptable a otros entornos donde quizás bash no esté en la misma ruta.
Leer más

Backups incrementales con tar

Sí, es cierto, hacía tiempo que no escribía nada en el blog y eso no puede ser. Después de un tiempo de parón, espero volver a ser más constante en las entradas.
En este caso, vamos a ver un método de hacer un backup incremental, pero sin ningún software adicional, sino empleando el comando tar.
La importancia de realizar backups no hace falta que la comente, pues es un tema muy sabido por todos. El método típico de hacer backup con tar, es comprimir todos los ficheros que así desees en un contenedor y darle un nombre, por ejemplo, una fecha. Si todos los finales de día lo hacemos, tenemos un backup bastante consistente y ante posibles fallos. El único problema, que ocupará mucho espacio! Para resolver este problema está el backup incremental y tar, como no podía ser de otra manera, también lo soporta. A continuación, dejo un ejemplo de cómo se debería de emplear tar para la realización de un backup incremental.
  • Crear el entorno de pruebas
    shell> mkdir -p test/aa test/bb test/cc
    shell> touch test/aa/a test/bb/b test/cc/c
    
  • Realizar el primer backup
    Importante aquí, la opción que le pasamos --listed-incremental file.
    shell> tar --listed-incremental test.metadata \
               -czf test.tar.gz test
    
  • Borrar y cambiar ficheros
    shell> rm test/aa/a
    shell> touch test/aa/aa
    shell> echo "hola" > test/bb/b
    
  • Volver a lanzar el backup incremental
    Cada incremental lo vamos añadiendo a un nuevo contenedor.
    shell> tar --listed-incremental test.metadata \
               -czf test.inc1.tar.gz test
    
  • Restaurar ficheros
    Para ello, necesitamos el fichero de backup completo y también los incrementales
    shell> mkdir restore
    shell> tar xzf test.tar.gz -C restore
    shell> tar --incremental \
               -xzf test.inc1.tar.gz -C restore
    
Como podemos apreciar que ha añadido el fichero creado pero también borrado el fichero eliminado en el momento de hacer el incremental. Espero que os haya resultado útil.
Como ya sabréis, realizar backups al mismo disco no es una buena idea, por lo que si no lo conoces, te recomiendo la lectura del tag bacula, que quizás te ayude a tener un backup más seguro.
Leer más

Grabación de sesiones de consola

No fui el primero, ni seré el último en preguntarse cómo grabar todo lo que estás haciendo en la consola de tu equipo Linux, par a continuación poder dejarlo a libre disposición.
hasta que conocí el software del que os voy a hablar hoy, la forma que tenía de hacerlo no era más que la de grabar toda la pantalla (o una región) y dejar luego el vídeo, por ejemplo en Youtube.
Pues bien, ahora ya no podrás decir que no conoces ttyrec, con el que podrás grabar todo el comportamiento de tu consola de una forma más limpia y rápida.

Instalación

ttyrec está disponible en prácticamente todos los repositorios oficiales de las principales distribuciones, así que para instalarlo,
shell> apt-get install ttyrec

Grabar

Comenzar una nueva sesión o grabación es muy sencillo. Únicamente tendremos que saber el nombre que le vamos a querer dar y a continuación,
shell> ttyrec -a git_usage.tty
Para pararla, emplearemos Control + c.

Reproducir

Una vez tengamos la grabación finalizada, tendremos un fichero que podemos reproducir las veces que queramos, únicamente tendremos que tener instalado ttyplay, que viene con el paquete ttyrec.
shell> ttyplay git_usage.tty
Por suerte, este tipo de ficheros, al almacenar texto plano ocupan muy poco, por lo que pasárselos a alguien es sencillo y no debería de darnos problema. De todas formas existen webs, como playterm.org que nos permiten subir el fichero e incrustarlo en una web o dejarlo público.

Referencias

Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios