13.4. Prueba de éxito

La parte más fundamental de una prueba unitaria es la construcción de casos de prueba individuales. Un caso de prueba responde a una única pregunta sobre el código que está probando.

Un caso de prueba debería ser capaz de...

Dado esto, construyamos el primer caso de prueba. Tenemos el siguiente requisito:

  1. toRoman debería devolver la representación en romanos de todos los enteros del 1 al 3999.

Ejemplo 13.2. testToRomanKnownValues


class KnownValues(unittest.TestCase):                           1
    knownValues = ( (1, 'I'),
                    (2, 'II'),
                    (3, 'III'),
                    (4, 'IV'),
                    (5, 'V'),
                    (6, 'VI'),
                    (7, 'VII'),
                    (8, 'VIII'),
                    (9, 'IX'),
                    (10, 'X'),
                    (50, 'L'),
                    (100, 'C'),
                    (500, 'D'),
                    (1000, 'M'),
                    (31, 'XXXI'),
                    (148, 'CXLVIII'),
                    (294, 'CCXCIV'),
                    (312, 'CCCXII'),
                    (421, 'CDXXI'),
                    (528, 'DXXVIII'),
                    (621, 'DCXXI'),
                    (782, 'DCCLXXXII'),
                    (870, 'DCCCLXX'),
                    (941, 'CMXLI'),
                    (1043, 'MXLIII'),
                    (1110, 'MCX'),
                    (1226, 'MCCXXVI'),
                    (1301, 'MCCCI'),
                    (1485, 'MCDLXXXV'),
                    (1509, 'MDIX'),
                    (1607, 'MDCVII'),
                    (1754, 'MDCCLIV'),
                    (1832, 'MDCCCXXXII'),
                    (1993, 'MCMXCIII'),
                    (2074, 'MMLXXIV'),
                    (2152, 'MMCLII'),
                    (2212, 'MMCCXII'),
                    (2343, 'MMCCCXLIII'),
                    (2499, 'MMCDXCIX'),
                    (2574, 'MMDLXXIV'),
                    (2646, 'MMDCXLVI'),
                    (2723, 'MMDCCXXIII'),
                    (2892, 'MMDCCCXCII'),
                    (2975, 'MMCMLXXV'),
                    (3051, 'MMMLI'),
                    (3185, 'MMMCLXXXV'),
                    (3250, 'MMMCCL'),
                    (3313, 'MMMCCCXIII'),
                    (3408, 'MMMCDVIII'),
                    (3501, 'MMMDI'),
                    (3610, 'MMMDCX'),
                    (3743, 'MMMDCCXLIII'),
                    (3844, 'MMMDCCCXLIV'),
                    (3888, 'MMMDCCCLXXXVIII'),
                    (3940, 'MMMCMXL'),
                    (3999, 'MMMCMXCIX'))                        2

    def testToRomanKnownValues(self):                           3
        """toRoman should give known result with known input"""
        for integer, numeral in self.knownValues:              
            result = roman.toRoman(integer)                     4 5
            self.assertEqual(numeral, result)                   6
1 Para escribir un caso de prueba, primero derivamos la clase TestCase del módulo unittest. Esta clase proporciona muchos métodos útiles que puede invocar desde el caso de prueba para comprobar condiciones específicas.
2 Una lista de pares entero/número que he verificado manualmente. Incluye los diez números más pequeños, los más grandes, cada número que se traduce a un único carácter numeral romano, y una muestra al azar de otros números válidos. El objetivo de una prueba unitaria no es probar cada caso posible, sino una muestra representativa.
3 Cada prueba individual es un método separado, que no debe tomar parámetros ni devolver valores. Si el método sale de forma normal sin lanzar una excepción, se considera que ha pasado la prueba; si el método lanza una excepción, se considera que ha fallado la prueba.
4 Aquí llamamos a la función toRoman (bien, no se ha escrito aún la función, pero una vez que lo esté, esta es la línea que la invocaría). Observe que hemos definido el API de la función toRoman: debe tomar un entero (el número a convertir) y devolver una cadena (la representación en números romanos). Si el API es diferente de eso, esta prueba se considera fallida.
5 Observe también que no estamos atrapando las excepciones cuando llamamos a toRoman. Esto es intencionado. toRoman no debería lanzar ninguna excepción cuando se le llama con una entrada válida, y estos valores de entrada son todos válidos. Si toRoman lanza una excepción, se considera que esta prueba es fallida.
6 Asumiendo que se haya definido e invocado correctamente la función toRoman, que haya terminado con éxito y devuelto un valor, el último paso es comprobar si devuelve el valor correcto. Ésta es una operación común y la clase TestCase proporciona un método para comprobar si dos valores son iguales, assertEqual. Si el resultado devuelto por toRoman (result) no coincide con el valor conocido que esperábamos (numeral), assertEqual lanzará una excepción y la prueba fallará. Si los dos valores son iguales assertEqual no hará nada. Si cada valor devuelto por toRoman coincide con el esperado, assertEqual no lanzará ninguna excepción, así que testToRomanKnownValues saldrá de forma normal eventualmente, lo que significará que toRoman ha pasado la prueba.