Configuración de prueba de unidad de Python

Migel Hewage Nimesha 15 febrero 2024
  1. Configuración de Python unittest
  2. Conclusión
Configuración de prueba de unidad de Python

Las pruebas unitarias verifican si una unidad de código en particular o un módulo se desempeña como esperaba el desarrollador. La mayoría de las veces, la unidad de código que probamos es una función.

Así mismo, podemos probar todas las funciones. Como práctica recomendada, al menos en el proceso de desarrollo, deberíamos realizar pruebas unitarias.

Entonces, en la etapa inicial del proceso de desarrollo, detecta errores y podemos corregirlos sin perder mucho tiempo. Si nos saltamos estas pruebas, será difícil corregir los errores a la hora de continuar con el proyecto.

Configuración de Python unittest

Python proporciona un marco diferente para las pruebas unitarias llamado unittest. El marco unittest ofrece algunas características.

Las pruebas que realizamos con este método son independientes entre sí. En otras palabras, el éxito o el fracaso de una prueba no depende de los resultados de otras pruebas.

También proporciona funciones de configuración () y desmontaje () y automatización de pruebas. La función setup() nos permite configurar las instrucciones a ejecutar antes de cada método de prueba.

La función teardown() describirá las instrucciones que se ejecutan después de cada método de prueba.

unittest nos brinda algunos conceptos esenciales para usar en las pruebas unitarias, como el dispositivo de prueba, el caso de prueba, el conjunto de pruebas y el ejecutor de pruebas. Este artículo trata sobre la creación de una función setup() para pruebas unitarias utilizando el marco unittest.

Crear funciones para probar

Primero, necesitamos construir algunas funciones para probar. Vamos a crear cuatro funciones para sumar, restar, multiplicar, dividir dos números y obtener el resto.

def add(a, b):
    return a + b


def subtract(a, b):
    return a - b


def multiply(a, b):
    return a * b


def divide(a, b):
    return a / b


def remainder(a, b):
    return a % b

Podemos probar las funciones anteriores usando la función print(), pero no es muy práctica con cientos o miles de códigos. Entonces, creemos un módulo para probar las funciones.

Crear el módulo de prueba

Deberíamos nombrar nuestro módulo de prueba de acuerdo con la convención de nomenclatura. Usamos test_ como la primera parte del nombre y luego el nombre del módulo.

Vamos a crear nuestro módulo de prueba para este tutorial como test_calc.py.

Convenio de denominación:

test_ < name >

Luego tenemos que importar el marco unittest y el módulo numCal a nuestro módulo de prueba. unittest lo incluye en la biblioteca estándar, por lo que podemos importarlo directamente. numCal es el módulo que necesitamos probar.

import unittest
import numCal

Como siguiente paso, podemos crear una clase que herede de unittest.TestCase para que tengamos acceso a más capacidades de prueba dentro de esa clase.

class TestNumCal(unittest.TestCase):

Dentro de la clase, creamos métodos para cada función. Necesitamos nombrar los métodos de acuerdo con la convención de nomenclatura al nombrarlos.

Cuando ejecutamos el módulo de prueba, sabrá qué método representa las pruebas porque la primera parte del nombre es la prueba. De lo contrario, no identificará los métodos de prueba y los omitirá.

Primero, creemos un método de prueba para la función add().

def test_add(self):
    self.assertEqual(numCal.add(10, 5), 15)

Como en todo método, self es el primer argumento del método test_add(). Hemos usado el método assertEqual() en la segunda línea.

Dado que nuestra clase TestNumCal hereda de unittest.TestCase, podemos acceder a todos los métodos de afirmación disponibles. Métodos como assertEqual(), assertNotEqual(), assertTrue(), assertFalse() y assertIn() se pueden usar en pruebas unitarias y hay muchos más.

El método assertEqual() comprueba la igualdad entre el valor que devuelve la función y el valor que esperamos.

Luego, debemos configurar el módulo de prueba para que se ejecute directamente desde el editor. De lo contrario, no se ejecutará cuando intentemos ejecutar el módulo de prueba.

Entonces, para eso, podemos usar el siguiente código.

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

Ahora nuestro código debería verse así.

import unittest
import numCal


class TestNumCal(unittest.TestCase):
    def test_add(self):
        self.assertEqual(numCal.add(10, 5), 15)


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

Ahora podemos probar la función add() ejecutando el módulo test_calc.py.

Producción:

función de adición de prueba

Aquí, el punto indica que pasó la prueba. Si la prueba falla, aparecerá F, y si hay un error, aparecerá un mensaje de error.

A continuación, el punto muestra cuántas unidades se probaron.

Ahora vamos a crear cuatro métodos de prueba más para probar las funciones restantes.

import unittest
import numCal


class TestNumCal(unittest.TestCase):
    def test_add(self):
        self.assertEqual(numCal.add(10, 5), 15)

    def test_subtract(self):
        self.assertEqual(numCal.subtract(10, 5), 5)

    def test_multiply(self):
        self.assertEqual(numCal.multiply(10, 5), 50)

    def test_divide(self):
        self.assertEqual(numCal.divide(10, 5), 2)

    def test_remainder(self):
        self.assertEqual(numCal.remainder(10, 5), 0)


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

Según cada función, debemos cambiar el nombre del método de prueba.

Producción:

realizó 5 pruebas

La parte difícil aquí es que el valor de cada función debe establecerse en cada método de prueba. Será un problema cuando tengamos cientos de métodos de prueba.

Si es necesario cambiar los valores, debemos revisar cada método de prueba y cambiarlos.

Podemos construir la función setup() para superar esto. A través de este método, solo necesitamos declarar los valores una vez. Luego, antes de cada método, se ejecuta.

Crear la función setUp()

def setUp(self):
    print("\nsetUp")
    self.num1 = 10
    self.num2 = 5

Después de configurar la función setup(), también es necesario cambiar los argumentos de las funciones. Primero, cambiemos el método test_add.

def test_add(self):
    print("Add")
    self.assertEqual(numCal.add(self.num1, self.num2), 15)

Como se mencionó anteriormente, podemos realizar los cambios en los métodos restantes, y nuestro código completo debería verse como el que se muestra a continuación.

Código completo:

import unittest
import numCal


class TestNumCal(unittest.TestCase):
    def setUp(self):
        print("\nsetUp")
        self.num1 = 10
        self.num2 = 5

    def test_add(self):
        print("Add")
        self.assertEqual(numCal.add(self.num1, self.num2), 15)

    def test_subtract(self):
        print("Subtract")
        self.assertEqual(numCal.subtract(self.num1, self.num2), 5)

    def test_multiply(self):
        print("Multiply")
        self.assertEqual(numCal.multiply(self.num1, self.num2), 50)

    def test_divide(self):
        print("Divide")
        self.assertEqual(numCal.divide(self.num1, self.num2), 2)

    def test_remainder(self):
        print("remainder")
        self.assertEqual(numCal.remainder(self.num1, self.num2), 0)


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

Producción:

función de configuración

En la salida, cinco puntos indican que las pruebas han pasado y el número de pruebas que se ejecutaron. Debajo, los valores se han establecido antes de cada prueba; para identificar eso, hemos puesto funciones print().

Entonces, antes de que comiencen los métodos de prueba, la función setup() ejecuta las instrucciones definidas y las pruebas se realizan usándolas.

Conclusión

En este artículo, hemos aprendido qué son las pruebas unitarias y el marco unittest y cómo construir un módulo de prueba. Lo más importante es que aprendimos a usar la función setup() para establecer algunas instrucciones definidas para ejecutar antes de cada método de prueba.

La función setup() es útil cuando hay muchas pruebas para ejecutar y cuando necesitamos cambiar los valores de los argumentos.

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

Artículo relacionado - Python Unit Test