Desarrollo dirigido por pruebas – Python y Pytest

pytest logo

Desarrollo dirigido por pruebas

Hola a todos, en esta entrada quiero hablar de un tema que me gusta mucho, y que estoy seguro a ustedes también, hablo del desarrollo dirigido por pruebas o TDD. En esta entrada veremos que es TDD, algunos ejemplos y conoceremos una excelente herramienta para llevar esta metodología de desarrollo a la práctica, Pytest.

¿Qué es el desarrollo dirigido por pruebas o TDD?

TDD proviene de Test-Driven Development, lo cual no es más que una técnica de diseño e implementación de software incluida dentro de la metodología ágil. TDD es una técnica para diseñar software que se centra en tres pilares fundamentales:

  • La implementación de las funciones justas que el cliente necesita y no más.
  • La minimización del número de defectos que llegan al software en fase de producción.
  • La producción de software modular, altamente reutilizable y preparado para el cambio.

Al dar los primeros pasos en este tema, muchos suelen caer en la idea equivocada de que TDD se utiliza para que el proyecto, o mejor aún, el código que se está escribiendo, termine cargado con una amplia cobertura de pruebas (casos de uso), y aunque esto no es del todo herrado, y siempre se agradece, la idea principal detrás de TDD es convertir a los programadores en verdaderos desarrolladores.

¿Qué quiero decir con esto? En principio, cualquier persona después de un tiempo de leer libros y ver videos en internet, puede escribir código, pero para considerarse un verdadero profesional, debes ir más allá, conocer metodologías, patrones de diseño de software, pruebas unitarias, etc. Y para lograr esto, TDD nos ayuda bastante.

Cuando por fin nos sentimos cómodos trabajando con TDD (desarrollo dirigido por pruebas) podemos contar con características que de otra manera, sería muy laborioso añadir a nuestro flujo de trabajo en el diseño de software.

Ciclo de un desarrollo dirigido por pruebas

  • Enfocarse en un requerimiento a la vez: Se elige de una lista de requerimientos, aquél que se cree que nos dará mayor conocimiento del problema y que a la vez sea fácilmente implementable.
  • Escribir una prueba: Se comienza escribiendo una prueba para el requisito. Para ello el programador debe entender claramente las especificaciones y los requisitos de la funcionalidad que está por implementar. Este paso nos orilla como programadores a tomar la perspectiva de un cliente considerando el código a través de sus interfaces.
  • Verificar que la prueba falla: Si la prueba no falla es porque el requerimiento ya estaba implementado o porque la prueba no ha sido escrita correctamente.
  • Escribir la implementación: Escribir el código lo más sencillo posible, a modo de que haga que la prueba funcione. Se usa la expresión “Mantenlo simple, Es**.” (“Keep It Simple, Stupid!”), conocida como principio_KISS.
  • Ejecutar las pruebas automatizadas: Verificar que todas las pruebas escritas funcionan correctamente.
  • Eliminación de duplicación de código: El paso final es la refactorización, que se utilizará principalmente para eliminar código duplicado. Se van añadiendo pequeños cambios al código a modo de iteraciones, siempre asegurandose de ejecutar las pruebas para asegurarse de que mantiene un correcto funcionamiento.
  • Actualización de la lista de requisitos: Se actualiza la lista de requerimientos tachando el requerimiento implementado. Asimismo se agregan requerimientos que se hayan visto como necesarios durante este ciclo y se agregan requerimientos de diseño, ya que puede darse el caso en que se encuentre un requerimiento que se encuentre ligado a uno ya establecido previamente.

Una de las mayores ventajas de escribir código utilizando TDD es que rara vez tienes que hacer uso de un depurador. Aunque como cualquier cosa tiene sus desventajas, la más importante, es que para llevar a cabo esta práctica correctamente se requiere de mucha paciencia y dedicación para que las pruebas (casos de uso) que establezcamos sean lo más adecuados posibles.

Ejemplos de TDD (desarrollo dirigido por pruebas) con Python

pytest logoPara los siguientes ejemplos voy a hacer uso de mi librería de testing preferidad de las opciones que podemos encontrar para Python, hablo de Pytest.

¿Qué es Pytest?

Cómo lo describen en su página oficial:

“The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.”

Y es que es verdad, existen bastantes opciones para desarrollar mediante TDD con Python, pero sólo con Pytest he podido encontrar esa flexibilidad y facilidad con la que me siento tan contento. Para utilizar pytest, basta con instalarlo como cualquier otro paquete


$ pip install pytest

Para escribir nuestras pruebas, debemos hacerlo utilizando archivos con el prefijo “test_”.

Realicemos un sencillo ejemplo del ciclo de desarrollo con TDD. Primero creamos un directorio de trabajo y nos posicionamos dentro del mismo.


$ mkdir [DIRECTORIO] && cd [DIRECTORIO]

No te olvides de reemplazar [DIRECTORIO] con el nombre que le quieras dar tu mismo, en mi caso será tdd_example. Ahora, en este directorio creamos el archivo donde escribiremos nuestro código, en mi caso se llamará test_add.py.


$ touch test_add.py

Ahora, comencemos a escribir nuestro código siguiendo TDD.

  • Recordando el ciclo del desarrollo dirigido por pruebas, debemos elegir un requerimiento, en mi caso será sumar 2 números.
  • Escribimos nuestra prueba.

# Prueba la función con los valores (4, 5)
# Resultado: 9 (True)
def test_add():
assert add(4, 5) == 9

  • Verificamos que la prueba implementada falle, ya que en este punto el requerimiento no se encuentra implementado.

$ pytest

Veremos como nos aparecen mensajes de error, diciendo que no se encuentra implementado el método add, justo lo que esperabamos.

  • El siguiente punto es escribir nuestra implementación.

def add(x, y):
return x + y

  • Ahora, volvemos a ejecutar la prueba para validar el correcto funcionamiento de nuestra implementación.

$ pytest

Nos dará una salida con información de la ejecución, y un mensaje diciendo que todo ha sido ejecutado correctamente.

Y bien, creo que es todo por ahora, aún faltaron algunos pasos, pero siendo un ejemplo tan básico, no lo vi necesario, así mismo, invito a todos a que realicen experimentos más complejos, y lean la documentación de pytest para que lo implementen en sus desarrollos del día a día.

Espero te haya agradado esta entrada, y cualquier comentario no dudes en hacermelo saber por este medio, o en mi cuenta de Twitter.

También te invito a que me sigas en mis redes (Twitter, Facebook) y si te gusta lo que escribo, compartas el blog.

Hasta la próxima.

Ejercicios de Programación: Calculemos el Factorial de un número

Calculemos el factorial de un número

Debido a qué me encuentro cansado después de un largo día en el trabajo, será una entrada breve, pero siempre con el objetivo de compartir algo por día, para así también me sirva como repaso, en esta ocasión, simplemente voy a mostrarles algunas maneras que conozco para calcular el Factorial de un número, claro, utilizando el lenguaje Python.

Nota: Para poder realizar la solución de un problema, primero que nada debemos entenderlo, en este caso, el problema es obtener el factorial de un número cualquiera, a estas alturas espero sepas como se calcula el factorial de un número, pero si no es así, déjame mostrarte. El factorial de un número, se calcula multiplicando este número por todos los números anteriores a él hasta el 1. Esto es:

6! = 6 * 5 * 4 * 3 * 2 * 1, lo que nos da como resultado 720.

Sabiendo esto, veamos que opciones tenemos con Python para llevar a cabo esta operación.

Nota 2: Para simpleza de la entrada, todas las formas que veremos, las probaremos calculando el factorial del número 6, obviamente el procedimiento será el mismo para cualquier número.

Haciéndolo de forma “sucia”

print(6 * 5 * 4 * 3 * 2 * 1)

Utilizando la función built-in de Python

from math import factorial
factorial(5)

Utilizando un ciclo “while”

def fact_1(n):
    factorial_total = 1
    while n > 1:
        factorial_total *= n
        n -= 1
    return factorial_total

Utilizando recursividad

def fact_recursividad(n):
    if n > 1:
        return n * fact_recursividad(n - 1)
    else:
        return 1

Utilizando recursividad y el operador ternario 😀

def fact_ternario(n):
    return n * fact_ternario(n - 1) if n > 1 else 1

EDICIÓN (24/04/2016):
Gracias a la observación de Daniel en los comentarios, añado la forma elemental para
realizar el procedimiento.
Saludos.

def fact(n):
    if n == 0:
        r = 1
    else:
        r = n * fact(n - 1)
    return r

Ahora, si ejecutas el código podrás notar que todos devuelven el mismo resultado para cualquier número, pero podemos observar que tenemos diferentes maneras de programar la solución.

Factorial: Resultados

 

 

 

 

Puedes encontrar el código utilizado en esta entrada, comentario de mejor foma en el siguiente repositorio de Github https://github.com/TheMushrr00m/factorial-python 😀

Si tienes alguna duda, no dudes en dejar tu comentario, si te parecio interesante o tienes algún punto en el que piensas que podría mejorar algo, por favor no dudes también en dejar tu comentario, de igual forma comparte la entrada para que pueda llegar a alguien a quien le pueda resultar útil. Saludos.

Valores Truthy y Falsy

Hola a todos, hace tiempo que no escribo en el blog, pero pienso que es buen momento para retomarlo, y que mejor que hacerlo sobre algo que me llamó la atención estos días, los valores Truthy y Falsy.

Para quienes me conocen, no es secreto que mi lenguaje favorito, aquél con el que comencé en la programación, y con el que me gusta hacerlo todo siempre que se me permite es Python.

Pero últimamente he estado trabajando mucho con Javascript, en especial, ganando experiencia con su nueva especificación ECMAscript 2015,.

Algo que me llamó la atención, fue leer acerca de la expresión que establece el titulo de esta entrada, los valores Truthy y Falsy. Todos conocemos que en los lenguajes de programación, tenemos los valores “booleanos” True y False, así que se podrán estar preguntar, ¿de qué rayos está hablando? Bien, en palabras fáciles de digerir, podemos decir que cada elemento del lenguaje tiene un valor booleano intrinsico-primitivo.

Valores Truthy y Falsy

Valores Truthy y Falsy

 

 

 

Teniendo primeramente los valores que ya todos conocemos True y False, pertenecientes a la clase bool, nos encontramos con lo siguiente:

Valores Falsy

None  # Valor None perteneciente a la clase NoneType.
0  # Valor 0 perteneciente a la clase int.
""  # Valor cadena vacía perteneciente a la clase str.
[]  # Valor lista vacía perteneciente a la clase list.
()  # Valor tupla vacía perteneciente a la clase tuple.
{}  # Valor diccionario vació perteneciente a la clase dict.

Así que no te convence eso…puedes probarlo por ti mismo, en el intérprete de Python prueba utilizando bool() para evaluar cada uno de esos datos, verás que todos evaluarán como False…¿ahora me crees?

Dicho esto, cualquier otro valor, es considerado un valor Truthy . Sencillo ¿cierto?

 

Valores Truthy y Falsy

 

 

 

 

 

 

 

 

En el caso de JS no existe mucha diferencia con respecto a Python,

Como valores Falsy (además de false)  tenemos:

0  // (cero) de la clase Number.
NaN  // (Not a Number) de la clase Number.
""  // (cadena vacía) de la clase String.
null  // de la clase Object.
undefined  // de la clase Undefined.

Valores Truthy:

En JS al igual que Python, cualquier otro valor diferente a los anteriores, es considerado como verdadero o Truthy además de algunos valores que pueden resultar curiosos como:

Infinity  // Number(Al igual que NaN, son números especiales de JS)
"0" , "true", "false"  // String
function(){}  // Function
[]  // Object (Array)
{}  // Object

Y bien, es todo por ahora, mi nuevo propósito es publicar una entrada por día,
por más pequeña que sea, para ganar ese habito, y poder yo mismo mejorar en la programación,
y como persona, puesto que una vez me dijeron qué cada día se aprende algo nuevo, y que si
esto no se cumplía, es porque estaba desaprovechando mi tiempo.

Así que es todo por hoy, espero les sirva está información, si tienen algún comentario no
duden en escribirlo, y si les parece interesante el articulo, sería un gran gesto que lo compartieras.

Si quieren saber un poco más sobre esto, aplicado a JS,
una buena referencia es el siguiente articulo:

Saludos 😀

Curso Python – Herramientas necesarias

Hola a todos los lectores:

 

En esta ocasión les dejo este que es el segundo video del “Curso Python”.

En este vídeo les muestro la forma de instalar las herramientas necesarias para el curso, las cuales son, el interprete del lenguaje de programación Python, y un editor de textos, el cual, en mi elección, será el editor Sublime Text.

Espero sus comentarios.

Cualquier sugerencia es recibida.

Hasta la próxima. Saludos.

Curso Python – Presentación

Hola a todos los lectores:

En esta ocasión, les dejo este vídeo que realicé como presentación del nuevo “Curso Python”, el cuál estaré impartiendo durante un tiempo.

En este curso les mostraré lo básico de la programación, utilizando este, que a mi parecer es actualmente uno de los mejores lenguajes.

Para llevar a cabo este curso, no se necesitarán conocimientos previos de programación.

Espero que dejen sus comentarios y que puedan compartir los vídeos.

Bien, espero les sirvan y compartan las aplicaciones que realicen 😀

Saludos.

TOR en Firefox OS

Bueno, como esto no deja de ser un “blog”, quiero aprovechar estos minutos libres que tengo, para comentarles este proyecto que traigo entre manos.

Se trata de poder navegar bajo la red TOR en Firefox OS, actualmente solo tengo un equipo para pruebas, se trata de mi querido Alcatel OT Fire.

Si no sabes que es, te recomiendo visitar el sitio oficial TOR.

Bien, hasta ahora todo parece ir de buena manera, al ejecutarlo vía ADB, corre “bien”, ya que en ocasiones no detecta la red y por ende no se puede navegar. Recordemos que en el navegador de nuestro equipo, aún no lleva implementada la opción de configurar proxys.

Les comentaré un poco, de que va la cosa:

  • Primero, es necesario compilar los binarios de TOR y copiarlos a nuestro equipo, este es un proceso “sencillo” para usuarios intermedios diría yo.
  • Luego debemos crear ciertas reglas de IPTABLES en nuestro dispositivo.
  • Debemos entonces acudir a nuestro equipo y verificar que podamos navegar, pero sobre todo, que estemos corriendo bajo la red cebolla. 😀

Como podrán observar, requiere de ciertos conocimientos, y no es una tarea sencilla, además de que no nos sirve de nada que tengamos que activar la navegación desde una PC ya que al reiniciar el equipo la configuración de IPTABLES vuelve a la normalidad.

Sigo tratando de codear una “app” que haga este proceso directamente desde el dispositivo. Por eso aún no he liberado los binarios ni nada de información.

También traigo entre manos un cliente para Twitter y la posibilidad de llevar y ejecutar Python en nuestro sistema, con este ultimo, estoy igual que con TOR, con ayuda de una PC funciona, pero aún debo hacer una “app” que lo haga desde el equipo. Me disculpo si no dejo imágenes, pero dejé mi teléfono olvidado en casa 🙁 Luego actualizaré la entrada.

Aprovecho de una vez, para disculparme si los enlaces del sitio tienen publicidad, pero es por ahora, la única forma que tengo de obtener un poco de ayuda monetaria, si piensan que mi trabajo es interesante, y desean apoyarme y motivarme a seguir trabajando de esta manera, usen los enlaces tal cual los dejo en el sitio, o si gustan hacerme alguna donación, déjenme un comentario, o envíen un mensaje a mi correo para contactarme y ver de que manera podrían apoyarme.

Saludos. 🙂