Pruebas unitarias con Python unittest Module

Ningún buen desarrollador implementa código sin realizar pruebas exhaustivas. La prueba unitaria es el proceso de probar los módulos individuales de un programa grande.

Este artículo discutirá cómo puede realizar pruebas unitarias de su código utilizando el módulo de prueba unitaria de Python. Primero, comprendamos cuáles son los tipos de pruebas.

Cuando se trata de pruebas, hay pruebas manuales y pruebas automáticas. La prueba manual es una técnica de prueba en la que los humanos realizan la prueba manualmente después de completar el desarrollo. La prueba de automatización es una técnica de prueba en la que los programas realizan la prueba automáticamente y nos dan los resultados.

Habría entendido que las pruebas manuales requieren mucho tiempo y son difíciles de realizar. Entonces, los desarrolladores escriben código para realizar pruebas (pruebas automáticas). Hay diferentes tipos de pruebas en las pruebas automatizadas. Algunos de ellos son pruebas unitarias, pruebas de integración, pruebas de extremo a extremo, pruebas de estrés, etc.,

Veamos el flujo estándar de pruebas.

  • Escribe o actualiza el código.
  • Escriba o actualice pruebas para diferentes casos para su código.
  • Ejecute las pruebas (ya sea manualmente o usando un corredor de prueba).
  • Vea los resultados de la prueba. Si hay algún error, corrígelo y repite los pasos.

Aquí, vamos a discutir el tipo de prueba más esencial y básico llamado prueba unitaria. Sin más preámbulos, profundicemos en el tutorial real.

¿Qué es la prueba unitaria?

La prueba unitaria es una técnica para probar un pequeño bloque de código independiente. El código de bloque pequeño será una función en la mayoría de los casos. La palabra independiente significa que no depende de otras piezas de código en el proyecto.

Digamos que tenemos que comprobar si una cadena es igual a «kirukiru.es» o no. Para eso, hemos escrito una función que toma un argumento y devuelve si es igual a “kirukiru.es” o no.

def is_equal_to_geekflare(string):
	return string == "kirukiru.es"

La función anterior no tiene dependencias de ningún otro código. Entonces, podemos probarlo de forma independiente dando diferentes entradas. La pieza de código independiente se puede utilizar en todo el proyecto.

Importancia de las pruebas unitarias

En general, el código de bloques independientes se puede utilizar en todo el proyecto. Por lo tanto, debe estar bien escrito y probado. Las pruebas unitarias son las pruebas utilizadas para probar esos tipos de bloques de código independientes. ¿Qué sucede si no usamos pruebas unitarias para nuestro proyecto?

Supongamos que no probamos pequeños bloques de código que se usan en todo el proyecto. Todas las demás pruebas, como las pruebas de integración, las pruebas de un extremo a otro, etc., que utilicen los otros pequeños bloques de código pueden fallar. Esto rompe la aplicación. Es por eso que los bloques de construcción básicos del código deben probarse bien.

Ahora, sabemos la importancia de las pruebas unitarias y las pruebas unitarias escritas para todos los bloques de código independientes. Dado que hemos realizado pruebas unitarias, otras pruebas como las pruebas de integración, las pruebas de extremo a extremo, etc., no fallarán debido al bloque de códigos independiente.

En las próximas secciones, veremos qué es el módulo unittest de Python y cómo usamos el módulo unittest para escribir pruebas unitarias en Python.

Nota: Suponemos que está familiarizado con las clases, módulos, etc. de Python. Si no está familiarizado con los conceptos intermedios de Python, como clases, módulos, etc., es posible que le resulte difícil comprender las siguientes secciones.

¿Qué es la prueba unitaria de Python?

Python unittest es un marco de prueba integrado para probar el código de Python. Dispone de un corredor de pruebas, que nos permite ejecutar las pruebas sin mucho esfuerzo. Por lo tanto, podemos usar el módulo unittest incorporado para realizar pruebas sin usar los módulos de terceros. Pero, cambia según sus requisitos. El módulo unittest incorporado es bueno para comenzar con las pruebas en Python.

Tenemos que seguir los pasos a continuación para probar el código Python usando el módulo unittest.

#1. Escribe el código.

#2. Importe el módulo unittest.

#3. Cree un archivo que comience con la prueba de palabras clave. Por ejemplo test_prime.py. La palabra clave test se utiliza para identificar los archivos de prueba.

#4. Cree una clase que extienda la clase unittest.TestCase.

#5. Escribe métodos (pruebas) dentro de la clase. Cada método contiene diferentes casos de prueba según sus requisitos. Debemos nombrar el método comenzando con la palabra clave de prueba.

#6. Ejecute las pruebas. Podemos ejecutar las pruebas de diferentes maneras.

  • Ejecute el comando python -m unittest test_filename.py.
  • Ejecutamos los archivos de prueba como archivos generales de Python con el comando python test_filename.py. Para que este método funcione, necesitamos invocar el método principal de unittest en el archivo de prueba.
  • Y finalmente, usando el método Discover. Podemos ejecutar automáticamente las pruebas con el comando python -m unittest discovery sin mencionar el nombre de archivo de la prueba. Encontrará las pruebas usando la convención de nomenclatura que seguimos. Por lo tanto, debemos nombrar nuestros archivos de prueba con la palabra clave test al inicio.

Generalmente, en las pruebas, comparamos la salida del código con la salida esperada. Entonces, para comparar las salidas unittest proporciona diferentes métodos. Puede encontrar la lista de funciones de comparación aquí.

Puedes entenderlos fácilmente sin ninguna dificultad. Son sencillos.

Eso es mucha teoría. Ahora debemos entrar en la codificación.

Nota: Si tiene alguna consulta sobre el módulo unittest, puede ir a la documentación y despeja tus dudas. Sin más demora, usemos el módulo unittest.

Pruebas unitarias en Python usando unittest

Primero escribiremos algunas funciones y luego nos centraremos en escribir las pruebas. Primero, abra una carpeta en su editor de código favorito. Y crea un archivo llamado utils.py. Pegue el siguiente código en el archivo.

import math


def is_prime(n):
    if n < 0:
        return 'Negative numbers are not allowed'

    if n <= 1:
        return False

    if n == 2:
        return True

    if n % 2 == 0:
        return False

    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True


def cubic(a):
    return a * a * a


def say_hello(name):
    return "Hello, " + name

Tenemos tres funciones diferentes en el archivo utils.py. Ahora, tenemos que probar cada función con diferentes casos de prueba. Escribamos las pruebas para la primera función is_prime.

#1. Cree un archivo llamado test_utils.py en la carpeta de muestra como utils.py.

#2. Importe el módulo utils y unittest.

#3. Cree una clase con el nombre TestUtils que extienda la clase unittest.TestCase. El nombre de la clase puede ser cualquier cosa. Trate de darle a la clase un nombre significativo.

#4. Dentro de la clase, escriba un método llamado test_is_prime que se acepte a sí mismo como argumento.

#5. Escriba diferentes casos de prueba con argumentos para is_prime y compare la salida con la salida esperada.

#6. Caso de prueba de ejemplo self.assertFalse(utils.is_prime(1)).

#7. Esperamos que la salida de is_prime(1) sea falsa en el caso anterior.

#8. Similar al caso anterior, haremos diferentes casos de prueba basados ​​en la función que estamos probando.

Veamos las pruebas.

import unittest

import utils


class TestUtils(unittest.TestCase):
    def test_is_prime(self):
        self.assertFalse(utils.is_prime(4))
        self.assertTrue(utils.is_prime(2))
        self.assertTrue(utils.is_prime(3))
        self.assertFalse(utils.is_prime(8))
        self.assertFalse(utils.is_prime(10))
        self.assertTrue(utils.is_prime(7))
        self.assertEqual(utils.is_prime(-3),
                         "Negative numbers are not allowed")


if __name__ == '__main__':
    unittest.main()

Estamos invocando el método principal de prueba unitaria del módulo para ejecutar las pruebas usando el comando python filename.py. Ahora, haz las pruebas.

Verá la salida similar a la siguiente salida.

$ python test_utils.py 
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Ahora, intente escribir los casos de prueba para otras funciones también. Piense en diferentes casos para las funciones y escriba pruebas para ellos. Eche un vistazo a las siguientes pruebas que se agregan a la clase anterior.

...


class TestUtils(unittest.TestCase):
    def test_is_prime(self):
        ...

    def test_cubic(self):
        self.assertEqual(utils.cubic(2), 8)
        self.assertEqual(utils.cubic(-2), -8)
        self.assertNotEqual(utils.cubic(2), 4)
        self.assertNotEqual(utils.cubic(-3), 27)

    def test_say_hello(self):
        self.assertEqual(utils.say_hello("kirukiru.es"), "Hello, kirukiru.es")
        self.assertEqual(utils.say_hello("Chandan"), "Hello, Chandan")
        self.assertNotEqual(utils.say_hello("Chandan"), "Hi, Chandan")
        self.assertNotEqual(utils.say_hello("Hafeez"), "Hi, Hafeez")


...

Usamos solo algunas de las funciones de comparación del módulo unittest. Puedes encontrar la lista completa aquí.

Hemos aprendido a escribir pruebas unitarias usando el módulo unittest. Ahora es el momento de ver diferentes formas de ejecutar las pruebas.

Cómo ejecutar pruebas usando unittest

Ya hemos visto una forma de ejecutar los casos de prueba en la sección anterior. Veamos las otras dos formas de ejecutar las pruebas usando el módulo unittest.

#1. Usando el nombre del archivo y el módulo unittest.

En este método, usaremos el módulo unittest y el nombre de archivo para ejecutar las pruebas. El comando para ejecutar las pruebas es python -m unittest filename.py. En nuestro caso, el comando para ejecutar las pruebas es python -m unittest test_utils.py.

#2. Usando el método de descubrimiento

Usaremos el método de descubrimiento del módulo unittest para detectar automáticamente todos los archivos de prueba y ejecutarlos. Para detectar automáticamente los archivos de prueba, debemos nombrarlos comenzando con la palabra clave prueba.

El comando para ejecutar las pruebas con el método de descubrimiento es python -m unittest discover. El comando detectará todos los archivos cuyos nombres comiencen con prueba y los ejecutará.

Conclusión 👩‍💻

Las pruebas unitarias son pruebas básicas en el mundo de la programación. Hay muchas otras pruebas en el mundo real. Trate de aprenderlos de uno en uno. Espero que este tutorial te ayude a escribir pruebas básicas en Python usando el módulo unittest. Hay bibliotecas de terceros como pytest, Robot Framework, nose, nose2, slash, etc. Puede explorarlas según los requisitos de su proyecto.

Felices pruebas 😎

También puede estar interesado en Preguntas y respuestas de la entrevista de Python.