Se preparó una traducción del artículo específicamente para los estudiantes del curso de Ingeniero de Python QA .
La prueba de código de unidad es una parte integral del ciclo de vida de desarrollo de software. Las pruebas unitarias también forman la base para realizar pruebas de regresión, es decir, garantizan que el sistema se comportará de acuerdo con el escenario cuando se agreguen nuevas características o cambien las existentes.
En este artículo, demostraré la idea básica de las pruebas unitarias en una clase. En la práctica, tendrá que escribir muchos casos de prueba, agregarlos al conjunto de pruebas y ejecutarlos todos juntos. La gestión de casos de prueba se discutirá en el próximo artículo. 
Hoy nos centraremos en probar el backend. Es decir, el desarrollador ha implementado algún proyecto de acuerdo con las especificaciones (por ejemplo, Calculator.py), y su tarea es asegurarse de que el código desarrollado realmente coincida con ellos (por ejemplo, usando 
TestCalculator.py ).
Suponga que escribió la clase Calculadora para realizar funciones computacionales básicas: suma, resta, multiplicación y división.
El código para esto está aquí ( 
Calculator.py ):
 
Ahora quiero ejecutar una prueba unitaria para comprender que la funcionalidad en la clase anterior funciona según lo planeado.
Python generalmente viene con el paquete 
unittest . Si no está en su sistema, use pip para instalarlo.
La prueba unitaria tiene la siguiente estructura:

setUp() y 
tearDown() son métodos estándar que vienen con el marco unittest (se definen en la clase unittest.TestCase). Dependiendo de su caso de prueba, puede anular o no anular estos dos métodos de manera predeterminada.
Es hora de mirar el código del caso de prueba. Aquí está el archivo 
TestCalculator.py .
 import unittest from Calculator import Calculator  
Aunque esto no es necesario, pero por regla general, llamo a la clase de prueba con el prefijo Test (en nuestro caso TestCalculator). Un requisito clave en esta clase es la presencia de la superclase 
unittest.TestCase .
Cada vez que se ejecuta este caso de prueba, el método setUp () se ejecuta primero. En nuestro caso, simplemente creamos un objeto de la clase Calculadora y lo guardamos como un atributo de la clase. Hay varios otros métodos predeterminados en la clase padre, que discutiremos más adelante.
Por ahora, todo lo que hará será escribir métodos 
test_xxx para probar cada método en la clase Calculadora. Tenga en cuenta que todos los métodos de prueba comienzan con el prefijo 
test_ . Esto le dice a Python usando el framework unittest que estos son métodos de prueba.
En cada uno de los métodos de prueba, utilicé el método 
assertEqual para comprobar si los métodos de la calculadora devuelven el valor esperado. Si el valor de retorno es igual al valor esperado, entonces la prueba tiene éxito, de lo contrario falla.
Hay muchos métodos de 
assert incorporados de los que hablaremos más adelante.
La última línea en el código anterior solo inicia el caso de prueba 
TestCalculator . Ejecuta cada método de prueba definido dentro de la clase y devuelve el resultado.
 python TestCalculator.py -v 
Verá una conclusión similar a la siguiente:
 test_add (__main__.TestCalculator) ... ok test_divide (__main__.TestCalculator) ... ok test_multiply (__main__.TestCalculator) ... ok test_subtract (__main__.TestCalculator) ... ok -------------------------------------------------------------------- Ran 4 tests in 0.000s OK 
¿Qué pasa si algo no funciona como se esperaba? Cambiemos el valor esperado de 
test_divide de 5 a 6 (5 es el valor correcto, ahora veremos qué sucede si falla. Esto no es un error en el código fuente, sino un error en el conjunto de pruebas, también puede tener errores en los conjuntos de pruebas, así que siempre verifique prueba scripts para errores!)
 import unittest from Calculator import Calculator  
Cuando ejecute este caso de prueba, obtendrá el siguiente resultado:
 test_add (__main__.TestCalculator) ... ok test_divide (__main__.TestCalculator) ... FAIL test_multiply (__main__.TestCalculator) ... ok test_subtract (__main__.TestCalculator) ... ok ==================================================================== FAIL: test_divide (__main__.TestCalculator) -------------------------------------------------------------------- Traceback (most recent call last): File "TestCalculator.py", line 23, in test_divide self.assertEqual(self.calculator.divide(10,2), 6) AssertionError: 5.0 != 6 -------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1) 
Aquí dice que 3 de 4 pruebas tuvieron éxito, pero una falló. En un escenario real, se supone que su caso de prueba es correcto, es decir, de esta manera ayuda a identificar una función que no se implementa correctamente.