Red de conocimiento informático - Problemas con los teléfonos móviles - ¡Las preguntas sobre Python necesitan respuestas!

¡Las preguntas sobre Python necesitan respuestas!

Pruebas unitarias

Si ha oído hablar del "Desarrollo basado en pruebas" (TDD: Test-Driven Development), las pruebas unitarias le resultan familiares.

El test unitario es una prueba que se utiliza para comprobar la corrección de un módulo, una función o una clase.

Por ejemplo, para la función abs(), podemos escribir los siguientes casos de prueba:

Ingrese un número positivo, como 1, 1,2, 0,99, y espere el valor de retorno. ser el mismo que la entrada;

Ingrese un número negativo, como -1, -1,2, -0,99, y espere que el valor de retorno sea opuesto al de la entrada;

Ingrese 0, espere un resultado de 0;

Ingrese un valor no numérico. Se espera que los tipos, como Ninguno, [], {}, generen TypeError.

Coloque los casos de prueba anteriores en un módulo de prueba para formar una prueba unitaria completa.

Si la prueba unitaria pasa, significa que la función que probamos puede funcionar normalmente. Si la prueba unitaria falla, hay un error en la función o las condiciones de prueba se ingresaron incorrectamente. En resumen, es necesario solucionarlo para que la prueba unitaria pueda pasar.

¿Cuál es la importancia de aprobar la prueba unitaria? Si realizamos modificaciones en el código de la función abs(), solo necesitamos ejecutar la prueba unitaria nuevamente. Si pasa, significa que nuestra modificación no afectará el comportamiento original de la función abs(). significa que nuestra modificación Si es inconsistente con el comportamiento original, modifique el código o modifique la prueba.

El mayor beneficio de este modelo de desarrollo basado en pruebas es garantizar que el comportamiento de un módulo de programa se ajuste a los casos de prueba que diseñamos. Cuando se modifique en el futuro, se puede garantizar en gran medida que el comportamiento del módulo seguirá siendo correcto.

Escribamos una clase Dict. Esta clase se comporta igual que dict, pero se puede acceder a ella a través de atributos. Se usa de la siguiente manera:

>>> d = Dict( a. =1, b=2)

>>> d['a']

1

>>> d.a

1

El código Mydict.py es el siguiente:

class Dict(dict):

def __init__(self, **kw):

super(Dict, self).__init__(**kw)

def __getattr__(self, clave):

prueba:

return self[clave ]

excepto KeyError:

elevar AttributeError(r"'Dict' objeto no tiene atributo '%s'" % clave)

def __setattr__(self, clave, valor):

self[clave] = valor

Para escribir pruebas unitarias, necesitamos introducir el módulo unittest que viene con Python y escribir mydict_test.py de la siguiente manera :

importar prueba unitaria

desde mydict importar Dict

clase TestDict(unittest.TestCase):

def test_init(self):

d = Dict(a=1, b='prueba')

self.assertEquals(d.a, 1)

self.assertEquals(d.b, 'prueba ')

self.assertTrue(isinstance(d, dict))

def test_key(self):

d = Dict()

d['key '] = 'valor'

self.assertEquals(d.key, 'value')

def test_attr(self):

d = Dict()

d.key = 'valor'

self.assertTrue('clave' en d)

self.assertEquals(d[ 'clave'], 'valor')

def test_keyerror(self):

d = Dict()

con self.assertRaises(KeyError):

valor = d['empty']

def test_attrerror(self):

d = Dict()

con self.assertRaises (AttributeError):

p>

valor = d.empty

Al escribir pruebas unitarias, necesitamos

Para escribir una clase de prueba, herede de unittest.TestCase.

Los métodos que comienzan con test son métodos de prueba. Los métodos que no comienzan con test no se consideran métodos de prueba y no se ejecutarán durante la prueba.

Para cada tipo de prueba, es necesario escribir un método test_xxx(). Dado que unittest.TestCase proporciona muchos juicios condicionales integrados, solo necesitamos llamar a estos métodos para afirmar si el resultado es el que esperamos. La aserción más utilizada es afirmarEquals():

self.assertEquals(abs(-1), 1) # Afirma que el resultado devuelto por la función es igual a 1

Otra aserción importante Es de esperar que se genere un error de un tipo específico. Por ejemplo, al acceder a una clave inexistente a través de d['empty'], la aserción arrojará un KeyError:

con self. .assertRaises(KeyError):

value = d['empty']

Al acceder a una clave inexistente a través de d.empty, esperamos que se genere un AttributeError:

con self.assertRaises(AttributeError):

value = d.empty

Ejecutar pruebas unitarias

Una vez escritas las pruebas unitarias, puede ejecutar las pruebas unitarias. La forma más sencilla de ejecutarlo es agregar dos líneas de código al final de mydict_test.py:

if __name__ == '__main__':

unittest.main()

De esta manera, puedes ejecutar mydict_test.py como un script de Python normal:

$ python mydict_test.py

Otro método más común es pasar el parámetro - m en la línea de comando unittest ejecuta pruebas unitarias directamente:

$ python -m unittest mydict_test

.....

------- ----- --------------------------------------------- ----- --------

Ejecutó 5 pruebas en 0.000 s

OK

Este es un enfoque recomendado porque puede realizar lotes ejecute muchas pruebas unitarias a la vez y existen muchas herramientas que pueden ejecutar estas pruebas unitarias automáticamente.

setUp y TearDown

Puedes escribir dos métodos especiales setUp() y teaDown() en pruebas unitarias. Estos dos métodos se ejecutarán antes y después de llamar a cada método de prueba.

¿Para qué se utilizan los métodos setUp() y tearDown()? Imagine que su prueba necesita iniciar una base de datos. En este momento, puede conectarse a la base de datos en el método setUp () y cerrar la base de datos en el método tearDown (). De esta manera, no es necesario repetir el mismo código. en cada método de prueba:

clase TestDict(unittest.TestCase):

def setUp(self):

print 'setUp...'

def tearDown(self) :

print 'tearDown...'

Puedes ejecutar la prueba nuevamente para ver si setUp... y tearDown... son Se imprime antes y después de llamar a cada método de prueba.

Resumen

Las pruebas unitarias pueden probar eficazmente el comportamiento de un determinado módulo de programa y son una garantía de confianza para futuras reconstrucciones de código.

Los casos de prueba para pruebas unitarias deben cubrir combinaciones de entrada comunes, condiciones de contorno y excepciones.

El código de prueba unitario debe ser muy simple. Si el código de prueba es demasiado complejo, el código de prueba en sí puede tener errores.

Pasar la prueba unitaria no significa que el programa esté libre de errores, pero definitivamente habrá errores en el programa si no se pasa.