UnitTest Framework - Guía rápida

La prueba unitaria es un método de prueba de software mediante el cual se prueban unidades individuales de código fuente, como funciones, métodos y clases, para determinar si son aptas para su uso. Intuitivamente, uno puede ver una unidad como la parte más pequeña que se puede probar de una aplicación. Las pruebas unitarias son pequeños fragmentos de código creados por los programadores durante el proceso de desarrollo. Constituye la base para las pruebas de componentes.

Las pruebas unitarias se pueden realizar de las dos formas siguientes:

Prueba manual Pruebas automatizadas

La ejecución de los casos de prueba manualmente sin el soporte de ninguna herramienta se conoce como prueba manual.

  • Dado que los casos de prueba son ejecutados por recursos humanos, es muy time consuming and tedious.

  • Dado que los casos de prueba deben ejecutarse manualmente, se requieren más probadores en las pruebas manuales.

  • Es menos confiable ya que es posible que las pruebas no se realicen con precisión cada vez debido a errores humanos.

  • No se puede realizar ninguna programación para escribir pruebas sofisticadas que obtengan información oculta.

Tomar el soporte de la herramienta y ejecutar los casos de prueba mediante la herramienta de automatización se conoce como prueba de automatización.

  • Fast Automation ejecuta casos de prueba significativamente más rápido que los recursos humanos.

  • los investment over human resources is less ya que los casos de prueba se ejecutan utilizando la herramienta de automatización.

  • Las pruebas de automatización realizan exactamente la misma operación cada vez que se ejecutan y are more reliable.

  • Probadores can program sophisticated tests para sacar información oculta.

JUnit es un marco de pruebas unitarias para el lenguaje de programación Java. JUnit ha sido importante en el desarrollo del desarrollo impulsado por pruebas y forma parte de una familia de marcos de pruebas unitarias conocidos colectivamente como xUnit que se originó con JUnit. Puedes encontrar el tutorial de JUnit aquí.

El marco de pruebas unitarias de Python, a veces denominado "PyUnit", es una versión en lenguaje Python de JUnit desarrollada por Kent Beck y Erich Gamma. PyUnit forma parte de la biblioteca estándar de Python a partir de la versión 2.1 de Python.

El marco de pruebas unitarias de Python admite la automatización de pruebas, el uso compartido del código de configuración y apagado para las pruebas, la agregación de pruebas en colecciones y la independencia de las pruebas del marco de informes. El módulo unittest proporciona clases que facilitan el apoyo a estas cualidades para un conjunto de pruebas.

Este tutorial ha sido preparado para principiantes para ayudarles a comprender la funcionalidad básica del marco de pruebas de Python. Después de completar este tutorial, se encontrará con un nivel moderado de experiencia en el uso del marco de prueba de Python, desde donde puede pasar a los siguientes niveles.

Debe tener una experiencia razonable en el desarrollo de software utilizando el lenguaje Python. Nuestro tutorial de Python es un buen lugar para comenzar a aprender Python. También es deseable el conocimiento de los conceptos básicos de las pruebas de software.

Configuración del entorno

Las clases necesarias para escribir pruebas se encuentran en el módulo 'unittest'. Si está utilizando versiones anteriores de Python (antes de Python 2.1), el módulo se puede descargar desdehttp://pyunit.sourceforge.net/. Sin embargo, el módulo unittest ahora es parte de la distribución estándar de Python; por lo tanto, no requiere una instalación separada.

'unittest' admite la automatización de pruebas, el intercambio de códigos de configuración y cierre para pruebas, la agregación de pruebas en colecciones y la independencia de las pruebas del marco de informes.

El módulo unittest proporciona clases que facilitan el apoyo a estas cualidades para un conjunto de pruebas.

Para lograr esto, unittest admite los siguientes conceptos importantes:

  • test fixture- Esto representa la preparación necesaria para realizar una o más pruebas y cualquier acción de limpieza asociada. Esto puede implicar, por ejemplo, la creación de directorios, bases de datos temporales o proxy o el inicio de un proceso de servidor.

  • test case- Ésta es la unidad de prueba más pequeña. Esto busca una respuesta específica a un conjunto particular de entradas. unittest proporciona una clase base,TestCase, que se puede utilizar para crear nuevos casos de prueba.

  • test suite- Esta es una colección de casos de prueba, conjuntos de pruebas o ambos. Esto se usa para agregar pruebas que deben ejecutarse juntas. Los conjuntos de pruebas son implementados por la clase TestSuite.

  • test runner- Este es un componente que organiza la ejecución de pruebas y proporciona el resultado al usuario. El corredor puede usar una interfaz gráfica, una interfaz textual o devolver un valor especial para indicar los resultados de la ejecución de las pruebas.

Crear una prueba unitaria

Los siguientes pasos están involucrados en la escritura de una prueba unitaria simple:

Step 1 - Importe el módulo unittest en su programa.

Step 2- Definir una función a probar. En el siguiente ejemplo, la función add () se someterá a prueba.

Step 3 - Cree un caso de prueba subclasificando unittest.TestCase.

Step 4- Definir una prueba como método dentro de la clase. El nombre del método debe comenzar con 'prueba'.

Step 5- Cada llamada de prueba afirma la función de la clase TestCase. Hay muchos tipos de afirmaciones. El siguiente ejemplo llama a la función assertEquals ().

Step 6 - La función assertEquals () compara el resultado de la función add () con el argumento arg2 y arroja assertionError si la comparación falla.

Step 7 - Finalmente, llame al método main () desde el módulo unittest.

import unittest
def add(x,y):
   return x + y
   
class SimpleTest(unittest.TestCase):
   def testadd1(self):
      self.assertEquals(add(4,5),9)
      
if __name__ == '__main__':
   unittest.main()

Step 8 - Ejecute el script anterior desde la línea de comandos.

C:\Python27>python SimpleTest.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

Step 9 - Los siguientes tres podrían ser los posibles resultados de una prueba -

No Señor Mensaje y descripción
1

OK

La prueba pasa. Se muestra 'A' en la consola.

2

FAIL

La prueba no pasa y genera una excepción AssertionError. Se muestra 'F' en la consola.

3

ERROR

La prueba genera una excepción distinta de AssertionError. Se muestra 'E' en la consola.

Estos resultados se muestran en la consola con '.', 'F' y 'E' respectivamente.

Interfaz de línea de comandos

El módulo unittest se puede utilizar desde la línea de comandos para ejecutar pruebas únicas o múltiples.

python -m unittest test1
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

unittest admite las siguientes opciones de línea de comandos. Para obtener una lista de todas las opciones de la línea de comandos, use el siguiente comando:

Python –m unittest -h

No Señor Opción y descripción
1

-h, --help

Mostrar este mensaje

2

v, --verbose

Salida detallada

3

-q, --quiet

Salida mínima

4

-f, --failfast

Deténgase en el primer fallo

5

-c, --catch

Captura control-C y muestra los resultados

6

-b, --buffer

Búfer stdout y stderr durante las ejecuciones de prueba

Este capítulo analiza las clases y métodos definidos en el módulo unittest. Hay cinco clases principales en este módulo.

Clase TestCase

El objeto de esta clase representa la unidad comprobable más pequeña. Contiene las rutinas de prueba y proporciona ganchos para preparar cada rutina y para la limpieza posterior.

Los siguientes métodos están definidos en la clase TestCase:

No Señor Método y descripción
1

setUp()

Método llamado para preparar el dispositivo de prueba. Esto se llama inmediatamente antes de llamar al método de prueba.

2

tearDown()

Método llamado inmediatamente después de que se haya llamado al método de prueba y se haya registrado el resultado. Esto se llama incluso si el método de prueba generó una excepción,

3

setUpClass()

Un método de clase llamado antes de las pruebas en una ejecución de clase individual.

4

tearDownClass()

Un método de clase llamado después de que se hayan ejecutado las pruebas en una clase individual.

5

run(result = None)

Ejecute la prueba, recopilando el resultado en el objeto de resultado de la prueba aprobado como resultado .

6

skipTest(reason)

Llamar a esto durante un método de prueba o setUp () omite la prueba actual.

7

debug()

Ejecute la prueba sin recopilar el resultado.

8

shortDescription()

Devuelve una descripción de una línea de la prueba.

Accesorios

Puede haber numerosas pruebas escritas dentro de una clase TestCase. Estos métodos de prueba pueden necesitar una conexión a la base de datos, archivos temporales u otros recursos para inicializarse. Estos se denominan accesorios. TestCase incluye un gancho especial para configurar y limpiar los accesorios necesarios para sus pruebas. Para configurar los dispositivos, anule setUp (). Para limpiar, anule tearDown ().

En el siguiente ejemplo, se escriben dos pruebas dentro de la clase TestCase. Ponen a prueba el resultado de la suma y la resta de dos valores. El método setup () inicializa los argumentos basados ​​en shortDescription () de cada prueba. El método teardown () se ejecutará al final de cada prueba.

import unittest

class simpleTest2(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      if name == "Add":
         self.a = 10
         self.b = 20
         print name, self.a, self.b
      if name == "sub":
         self.a = 50
         self.b = 60
         print name, self.a, self.b
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
if __name__ == '__main__':
   unittest.main()

Ejecute el código anterior desde la línea de comando. Da la siguiente salida:

C:\Python27>python test2.py
Add 10 20
F
end of test Add
sub 50 60
end of test sub
.
================================================================
FAIL: testadd (__main__.simpleTest2)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
   File "test2.py", line 21, in testadd
      self.assertTrue(result == 100)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 2 tests in 0.015s

FAILED (failures = 1)

Accesorio de clase

La clase TestCase tiene un método setUpClass () que se puede anular para ejecutar antes de la ejecución de pruebas individuales dentro de una clase TestCase. De manera similar, el método tearDownClass () se ejecutará después de todas las pruebas en la clase. Ambos métodos son métodos de clase. Por lo tanto, deben decorarse con la directiva @classmethod.

El siguiente ejemplo demuestra el uso de estos métodos de clase:

import unittest

class TestFixtures(unittest.TestCase):

   @classmethod
   def setUpClass(cls):
      print 'called once before any tests in class'

   @classmethod
   def tearDownClass(cls):
      print '\ncalled once after all tests in class'

   def setUp(self):
      self.a = 10
      self.b = 20
      name = self.shortDescription()
      print '\n',name
   def tearDown(self):
      print '\nend of test',self.shortDescription()

   def test1(self):
      """One"""
      result = self.a+self.b
      self.assertTrue(True)
   def test2(self):
      """Two"""
      result = self.a-self.b
      self.assertTrue(False)
      
if __name__ == '__main__':
unittest.main()

Clase TestSuite

El marco de prueba de Python proporciona un mecanismo útil mediante el cual las instancias de casos de prueba se pueden agrupar de acuerdo con las características que prueban. Este mecanismo está disponible mediante la clase TestSuite en el módulo unittest.

Los siguientes pasos están involucrados en la creación y ejecución de un conjunto de pruebas.

Step 1 - Cree una instancia de la clase TestSuite.

suite = unittest.TestSuite()

Step 2 - Agregue pruebas dentro de una clase TestCase en la suite.

suite.addTest(testcase class)

Step 3 - También puede usar el método makeSuite () para agregar pruebas de una clase

suite = unittest.makeSuite(test case class)

Step 4 - También se pueden agregar pruebas individuales en la suite.

suite.addTest(testcaseclass(""testmethod")

Step 5 - Crea un objeto de la clase TestTestRunner.

runner = unittest.TextTestRunner()

Step 6 - Llame al método run () para ejecutar todas las pruebas en la suite

runner.run (suite)

Los siguientes métodos están definidos en la clase TestSuite:

No Señor Método y descripción
1

addTest()

Agrega un método de prueba en la suite de pruebas.

2

addTests()

Agrega pruebas de varias clases de TestCase.

3

run()

Ejecuta las pruebas asociadas con esta suite y recopila el resultado en el objeto de resultado de la prueba.

4

debug()

Ejecuta las pruebas asociadas con esta suite sin recopilar el resultado.

5

countTestCases()

Devuelve el número de pruebas representadas por este objeto de prueba.

El siguiente ejemplo muestra cómo utilizar la clase TestSuite:

import unittest
class suiteTest(unittest.TestCase):
   def setUp(self):
      self.a = 10
      self.b = 20
      
   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertTrue(result == 100)
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
      
def suite():
   suite = unittest.TestSuite()
##   suite.addTest (simpleTest3("testadd"))
##   suite.addTest (simpleTest3("testsub"))
   suite.addTest(unittest.makeSuite(simpleTest3))
   return suite
   
if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   runner.run (test_suite)

Puede experimentar con el método addTest () descomentando las líneas y la declaración de comentario con el método makeSuite ().

Clase TestLoader

El paquete unittest tiene la clase TestLoader que se utiliza para crear conjuntos de pruebas a partir de clases y módulos. De forma predeterminada, la instancia unittest.defaultTestLoader se crea automáticamente cuando se llama al método unittest.main (0. Sin embargo, una instancia explícita permite la personalización de ciertas propiedades.

En el siguiente código, las pruebas de dos clases se recopilan en una lista mediante el objeto TestLoader.

import unittest
testList = [Test1, Test2]
testLoad = unittest.TestLoader()

TestList = []
for testCase in testList:
   testSuite = testLoad.loadTestsFromTestCase(testCase)
   TestList.append(testSuite)
   
newSuite = unittest.TestSuite(TestList)
runner = unittest.TextTestRunner()
runner.run(newSuite)

La siguiente tabla muestra una lista de métodos en la clase TestLoader:

S. No Método y descripción
1

loadTestsFromTestCase()

Devuelve un conjunto de todos los casos de prueba contenidos en una clase TestCase

2

loadTestsFromModule()

Devuelve un conjunto de todos los casos de prueba contenidos en el módulo dado.

3

loadTestsFromName()

Devuelve un conjunto de todos los casos de prueba dado un especificador de cadena.

4

discover()

Encuentre todos los módulos de prueba recurriendo a subdirectorios desde el directorio de inicio especificado y devuelva un objeto TestSuite

Clase TestResult

Esta clase se utiliza para recopilar información sobre las pruebas que han tenido éxito y las pruebas que han fallado. Un objeto TestResult almacena los resultados de un conjunto de pruebas. El método TestRunner.run () devuelve una instancia de TestResult.

Las instancias de TestResult tienen los siguientes atributos:

No Señor Atributo y descripción
1

Errors

Una lista que contiene 2 tuplas de instancias de TestCase y cadenas que contienen rastreos formateados. Cada tupla representa una prueba que generó una excepción inesperada.

2

Failures

Una lista que contiene 2 tuplas de instancias de TestCase y cadenas que contienen rastreos formateados. Cada tupla representa una prueba en la que se señaló explícitamente una falla mediante los métodos TestCase.assert * ().

3

Skipped

Una lista que contiene 2 tuplas de instancias de TestCase y cadenas que contienen el motivo para omitir la prueba.

4

wasSuccessful()

Devuelve True si todas las pruebas ejecutadas hasta ahora han pasado; de lo contrario, devuelve False.

5

stop()

Se puede llamar a este método para indicar que se debe cancelar el conjunto de pruebas que se están ejecutando.

6

startTestRun()

Se llama una vez antes de que se ejecuten las pruebas.

7

stopTestRun()

Se llama una vez después de ejecutar todas las pruebas.

8

testsRun

El número total de pruebas realizadas hasta el momento.

9

Buffer

Si se establece en verdadero, sys.stdout y sys.stderr se almacenará en búfer entre startTest () y stopTest () que se llaman.

El siguiente código ejecuta un conjunto de pruebas:

if __name__ == '__main__':
   runner = unittest.TextTestRunner()
   test_suite = suite()
   result = runner.run (test_suite)
   
   print "---- START OF TEST RESULTS"
   print result

   print "result::errors"
   print result.errors

   print "result::failures"
   print result.failures

   print "result::skipped"
   print result.skipped

   print "result::successful"
   print result.wasSuccessful()
   
   print "result::test-run"
   print result.testsRun
   print "---- END OF TEST RESULTS"

El código cuando se ejecuta muestra la siguiente salida:

---- START OF TEST RESULTS
<unittest.runner.TextTestResult run = 2 errors = 0 failures = 1>
result::errors
[]
result::failures
[(<__main__.suiteTest testMethod = testadd>, 'Traceback (most recent call last):\n
   File "test3.py", line 10, in testadd\n 
   self.assertTrue(result == 100)\nAssert
   ionError: False is not true\n')]
result::skipped
[]
result::successful
False
result::test-run
2
---- END OF TEST RESULTS

El marco de prueba de Python utiliza la función assert () incorporada de Python que prueba una condición particular. Si la aserción falla, se generará un AssertionError. El marco de prueba identificará la prueba como Falla. Otras excepciones se tratan como Error.

Los siguientes tres conjuntos de funciones de aserción se definen en el módulo unittest:

  • Declaraciones booleanas básicas
  • Declaraciones comparativas
  • Declaraciones para colecciones

Las funciones de aserción básicas evalúan si el resultado de una operación es Verdadero o Falso. Todos los métodos de aserción aceptan unmsg argumento que, si se especifica, se utiliza como mensaje de error en caso de falla.

No Señor Método y descripción
1

assertEqual(arg1, arg2, msg = None)

Pruebe que arg1 y arg2 sean iguales. Si los valores no son iguales, la prueba fallará.

2

assertNotEqual(arg1, arg2, msg = None)

Pruebe que arg1 y arg2 no sean iguales. Si los valores son iguales, la prueba fallará.

3

assertTrue(expr, msg = None)

Prueba que expr sea ​​cierto. Si es falso, la prueba falla

4

assertFalse(expr, msg = None)

Prueba que expr sea ​​falso. Si es cierto, la prueba falla

5

assertIs(arg1, arg2, msg = None)

Pruebe que arg1 y arg2 se evalúan en el mismo objeto.

6

assertIsNot(arg1, arg2, msg = None)

Pruebe que arg1 y arg2 no se evalúen en el mismo objeto.

7

assertIsNone(expr, msg = None)

Pruebe que expr sea ​​None. Si no es Ninguno, la prueba falla

8

assertIsNotNone(expr, msg = None)

Pruebe que expr no sea None. Si ninguno, la prueba falla

9

assertIn(arg1, arg2, msg = None)

Pruebe que arg1 esté en arg2 .

10

assertNotIn(arg1, arg2, msg = None)

Pruebe que arg1 no esté en arg2 .

11

assertIsInstance(obj, cls, msg = None)

Prueba que obj es una instancia de cls

12

assertNotIsInstance(obj, cls, msg = None)

Prueba que obj no es una instancia de cls

Algunas de las funciones de aserción anteriores se implementan en el siguiente código:

import unittest

class SimpleTest(unittest.TestCase):
   def test1(self):
      self.assertEqual(4 + 5,9)
   def test2(self):
      self.assertNotEqual(5 * 2,10)
   def test3(self):
      self.assertTrue(4 + 5 == 9,"The result is False")
   def test4(self):
      self.assertTrue(4 + 5 == 10,"assertion fails")
   def test5(self):
      self.assertIn(3,[1,2,3])
   def test6(self):
      self.assertNotIn(3, range(5))

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

Cuando se ejecuta el script anterior, test2, test4 y test6 mostrarán falla y otros se ejecutarán correctamente.

FAIL: test2 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "C:\Python27\SimpleTest.py", line 9, in test2
      self.assertNotEqual(5*2,10)
AssertionError: 10 == 10

FAIL: test4 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "C:\Python27\SimpleTest.py", line 13, in test4
      self.assertTrue(4+5==10,"assertion fails")
AssertionError: assertion fails

FAIL: test6 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "C:\Python27\SimpleTest.py", line 17, in test6
      self.assertNotIn(3, range(5))
AssertionError: 3 unexpectedly found in [0, 1, 2, 3, 4]

----------------------------------------------------------------------            
Ran 6 tests in 0.001s                                                             
                                                                                  
FAILED (failures = 3)

El segundo conjunto de funciones de aserción son comparative asserts −

  • assertAlmostEqual (primero, segundo, lugares = 7, msg = Ninguno, delta = Ninguno)

    Pruebe que el primero y el segundo son aproximadamente (o no aproximadamente) iguales calculando la diferencia, redondeando al número dado de lugares decimales (predeterminado 7),

  • assertNotAlmostEqual (primero, segundo, lugares, mensaje, delta)

    Pruebe que el primero y el segundo no sean aproximadamente iguales calculando la diferencia, redondeando al número dado de lugares decimales (predeterminado 7) y comparando con cero.

    En las dos funciones anteriores, si se proporciona delta en lugar de lugares, la diferencia entre el primero y el segundo debe ser menor o igual a (o mayor que) delta.

    Proporcionar tanto delta como de lugares genera un TypeError.

  • assertGreater (primero, segundo, msg = Ninguno)

    Pruebe que el primero sea ​​mayor que el segundo según el nombre del método. Si no, la prueba fallará.

  • assertGreaterEqual (primero, segundo, msg = Ninguno)

    Pruebe que el primero sea ​​mayor o igual que el segundo según el nombre del método. Si no, la prueba fallará

  • assertLess (primero, segundo, msg = Ninguno)

    Pruebe que el primero sea ​​menor que el segundo, según el nombre del método. Si no, la prueba fallará

  • assertLessEqual (primero, segundo, msg = Ninguno)

    Pruebe que el primero sea ​​menor o igual al segundo según el nombre del método. Si no, la prueba fallará.

  • assertRegexpMatches (texto, regexp, msg = Ninguno)

    Pruebe que una búsqueda de expresiones regulares coincida con el texto. En caso de falla, el mensaje de error incluirá el patrón y el texto. regexp puede ser un objeto de expresión regular o una cadena que contiene una expresión regular adecuada para su uso porre.search().

  • assertNotRegexpMatches (texto, regexp, msg = Ninguno)

    Verifica que una búsqueda de expresiones regulares no coincida con el texto . Falla con un mensaje de error que incluye el patrón y la parte del texto que coincide. regexp puede ser un objeto de expresión regular o una cadena que contiene una expresión regular adecuada para su uso porre.search().

Las funciones de aserción se implementan en el siguiente ejemplo:

import unittest
import math
import re

class SimpleTest(unittest.TestCase):
   def test1(self):
      self.assertAlmostEqual(22.0/7,3.14)
   def test2(self):
      self.assertNotAlmostEqual(10.0/3,3)
   def test3(self):
      self.assertGreater(math.pi,3)
   def test4(self):
      self.assertNotRegexpMatches("Tutorials Point (I) Private Limited","Point")

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

El script anterior informa test1 y test4 como Failure. En test1, la división de 22/7 no está dentro de los 7 lugares decimales de 3,14. De manera similar, dado que el segundo argumento coincide con el texto del primer argumento, test4 da como resultado AssertionError.

=====================================================FAIL: test1 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "asserttest.py", line 7, in test1
      self.assertAlmostEqual(22.0/7,3.14)
AssertionError: 3.142857142857143 != 3.14 within 7 places
================================================================
FAIL: test4 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "asserttest.py", line 13, in test4
      self.assertNotRegexpMatches("Tutorials Point (I) Private Limited","Point")
AssertionError: Regexp matched: 'Point' matches 'Point' in 'Tutorials Point (I)
Private Limited'
----------------------------------------------------------------------

Ran 4 tests in 0.001s                                                             
                                                                                  
FAILED (failures = 2)

Afirmar para colecciones

Este conjunto de funciones de aserción está diseñado para usarse con tipos de datos de colección en Python, como Lista, Tupla, Diccionario y Conjunto.

No Señor Método y descripción
1

assertListEqual (list1, list2, msg = None)

Comprueba que dos listas son iguales. De lo contrario, se crea un mensaje de error que muestra solo las diferencias entre los dos.

2

assertTupleEqual (tuple1, tuple2, msg = None)

Prueba que dos tuplas son iguales. De lo contrario, se crea un mensaje de error que muestra solo las diferencias entre los dos.

3

assertSetEqual (set1, set2, msg = None)

Prueba que dos conjuntos son iguales. De lo contrario, se crea un mensaje de error que enumera las diferencias entre los conjuntos.

4

assertDictEqual (expected, actual, msg = None)

Prueba que dos diccionarios son iguales. Si no es así, se genera un mensaje de error que muestra las diferencias en los diccionarios.

El siguiente ejemplo implementa los métodos anteriores:

import unittest

class SimpleTest(unittest.TestCase):
   def test1(self):
      self.assertListEqual([2,3,4], [1,2,3,4,5])
   def test2(self):
      self.assertTupleEqual((1*2,2*2,3*2), (2,4,6))
   def test3(self):
      self.assertDictEqual({1:11,2:22},{3:33,2:22,1:11})

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

En el ejemplo anterior, test1 y test3 muestran AssertionError. El mensaje de error muestra las diferencias en los objetos Lista y Diccionario.

FAIL: test1 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "asserttest.py", line 5, in test1
      self.assertListEqual([2,3,4], [1,2,3,4,5])
AssertionError: Lists differ: [2, 3, 4] != [1, 2, 3, 4, 5]

First differing element 0:
2
1

Second list contains 2 additional elements.
First extra element 3:
4

- [2, 3, 4]
+ [1, 2, 3, 4, 5]
? +++       +++

FAIL: test3 (__main__.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "asserttest.py", line 9, in test3
      self.assertDictEqual({1:11,2:22},{3:33,2:22,1:11})
AssertionError: {1: 11, 2: 22} != {1: 11, 2: 22, 3: 33}
- {1: 11, 2: 22}
+ {1: 11, 2: 22, 3: 33}
?              +++++++
                                                                                  
----------------------------------------------------------------------            
Ran 3 tests in 0.001s                                                             
                                                                                  
FAILED (failures = 2)

La clase TestLoader tiene una función discover (). El marco de prueba de Python usa esto para un descubrimiento de prueba simple. Para que sean compatibles, los módulos y paquetes que contienen pruebas deben poder importarse desde el directorio de nivel superior.

El siguiente es el uso básico de la línea de comandos del descubrimiento de pruebas:

Python –m unittest discover

El intérprete intenta cargar todos los módulos que contienen la prueba del directorio actual y los directorios internos de forma recursiva. Otras opciones de la línea de comando son:

No Señor Opciones y descripción
1

-v, --verbose

Salida detallada

2

-s, --start-directory

directorio Directorio para iniciar el descubrimiento (. predeterminado)

3

-p, --pattern

patrón Patrón para que coincida con los archivos de prueba (prueba * .py predeterminado)

4

-t, --top-level-directory

directorio Directorio de nivel superior del proyecto (por defecto es el directorio de inicio)

Por ejemplo, para descubrir las pruebas en módulos cuyos nombres comienzan con 'assert' en el directorio 'pruebas', se utiliza la siguiente línea de comando:

C:\python27>python –m unittest –v –s "c:\test" –p "assert*.py"

El descubrimiento de pruebas carga las pruebas importándolas. Una vez que el descubrimiento de prueba ha encontrado todos los archivos de prueba del directorio de inicio que especifique, convierte las rutas en nombres de paquetes para importar.

Si proporciona el directorio de inicio como un nombre de paquete en lugar de una ruta a un directorio, entonces Discover asume que la ubicación desde la que importa es la ubicación deseada, por lo que no recibirá la advertencia.

Se ha agregado soporte para omitir pruebas desde Python 2.7. Es posible omitir el método de prueba individual o la clase TestCase, tanto condicional como incondicionalmente. El marco permite que una determinada prueba se marque como un "error esperado". Esta prueba 'fallará' pero no se contará como fallada en TestResult.

Para omitir un método incondicionalmente, se puede usar el siguiente método de clase unittest.skip ():

import unittest

   def add(x,y):
      return x+y

class SimpleTest(unittest.TestCase):
   @unittest.skip("demonstrating skipping")
   def testadd1(self):
      self.assertEquals(add(4,5),9)

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

Dado que skip () es un método de clase, tiene el prefijo @ token. El método toma un argumento: un mensaje de registro que describe el motivo del salto.

Cuando se ejecuta el script anterior, se muestra el siguiente resultado en la consola:

C:\Python27>python skiptest.py
s
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK (skipped = 1)

El carácter 's' indica que se ha omitido una prueba.

La sintaxis alternativa para omitir la prueba es usar el método de instancia skipTest () dentro de la función de prueba.

def testadd2(self):
   self.skipTest("another method for skipping")
   self.assertTrue(add(4 + 5) == 10)

Los siguientes decoradores implementan saltos de prueba y fallas esperadas:

No Señor Método y descripción
1

unittest.skip(reason)

Sáltese incondicionalmente la prueba decorada. El motivo debe describir por qué se omite la prueba.

2

unittest.skipIf(condition, reason)

Omita la prueba decorada si la condición es verdadera.

3

unittest.skipUnless(condition, reason)

Omita la prueba decorada a menos que la condición sea verdadera.

4

unittest.expectedFailure()

Marque la prueba como un error esperado. Si la prueba falla cuando se ejecuta, la prueba no se cuenta como falla.

El siguiente ejemplo demuestra el uso de la omisión condicional y la falla esperada.

import unittest

class suiteTest(unittest.TestCase):
   a = 50
   b = 40
   
   def testadd(self):
      """Add"""
      result = self.a+self.b
      self.assertEqual(result,100)

   @unittest.skipIf(a>b, "Skip over this routine")
   def testsub(self):
      """sub"""
      result = self.a-self.b
      self.assertTrue(result == -10)
   
   @unittest.skipUnless(b == 0, "Skip over this routine")
   def testdiv(self):
      """div"""
      result = self.a/self.b
      self.assertTrue(result == 1)

   @unittest.expectedFailure
   def testmul(self):
      """mul"""
      result = self.a*self.b
      self.assertEqual(result == 0)

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

En el ejemplo anterior, se omitirán testsub () y testdiv (). En el primer caso a> b es cierto, mientras que en el segundo caso b == 0 no es cierto. Por otro lado, testmul () se ha marcado como error esperado.

Cuando se ejecuta el script anterior, dos pruebas omitidas muestran 's' y el error esperado se muestra como 'x'.

C:\Python27>python skiptest.py
Fsxs
================================================================
FAIL: testadd (__main__.suiteTest)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
   File "skiptest.py", line 9, in testadd
      self.assertEqual(result,100)
AssertionError: 90 != 100

----------------------------------------------------------------------
Ran 4 tests in 0.000s

FAILED (failures = 1, skipped = 2, expected failures = 1)

El marco de prueba de Python proporciona los siguientes métodos de afirmación para verificar que se generen excepciones.

assertRaises (excepción, invocable, * args, ** kwds)

Pruebe que se genera una excepción (primer argumento) cuando se llama a una función con cualquier argumento posicional o de palabra clave. La prueba pasa si se genera la excepción esperada, es un error si se genera otra excepción o falla si no se genera ninguna excepción. Para capturar cualquiera de un grupo de excepciones, una tupla que contenga las clases de excepción se puede pasar como excepción.

En el siguiente ejemplo, se define una función de prueba para comprobar si se genera ZeroDivisionError.

import unittest

def div(a,b):
   return a/b
class raiseTest(unittest.TestCase):
   def testraise(self):
      self.assertRaises(ZeroDivisionError, div, 1,0)

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

La función testraise () usa la función assertRaises () para ver si la división por cero ocurre cuando se llama a la función div (). El código anterior generará una excepción. Pero cambia los argumentos a la función div () de la siguiente manera:

self.assertRaises(ZeroDivisionError, div, 1,1)

Cuando se ejecuta un código con estos cambios, la prueba falla porque no ocurre ZeroDivisionError.

F
================================================================
FAIL: testraise (__main__.raiseTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "raisetest.py", line 7, in testraise
      self.assertRaises(ZeroDivisionError, div, 1,1)
AssertionError: ZeroDivisionError not raised

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures = 1)

assertRaisesRegexp (excepción, regexp, invocable, * args, ** kwds)

Prueba que regexp coincide con la representación de cadena de la excepción generada. regexp puede ser un objeto de expresión regular o una cadena que contenga una expresión regular adecuada para ser usada por re.search ().

El siguiente ejemplo muestra cómo se usa assertRaisesRegexp ():

import unittest
import re

class raiseTest(unittest.TestCase):
   def testraiseRegex(self):
      self.assertRaisesRegexp(TypeError, "invalid", reg,"Point","TutorialsPoint")
      
if __name__ == '__main__':
   unittest.main()

Aquí, la prueba testraseRegex () no falla como primer argumento. "Point" se encuentra en la segunda cadena de argumentos.

================================================================
FAIL: testraiseRegex (__main__.raiseTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "C:/Python27/raiseTest.py", line 11, in testraiseRegex
      self.assertRaisesRegexp(TypeError, "invalid", reg,"Point","TutorialsPoint")
AssertionError: TypeError not raised
----------------------------------------------------------------------

Sin embargo, el cambio se muestra a continuación:

self.assertRaisesRegexp(TypeError, "invalid", reg,123,"TutorialsPoint")

Se lanzará la excepción TypeError. Por lo tanto, se mostrará el siguiente resultado:

================================================================
FAIL: testraiseRegex (__main__.raiseTest)
----------------------------------------------------------------------
Traceback (most recent call last):
   File "raisetest.py", line 11, in testraiseRegex
      self.assertRaisesRegexp(TypeError, "invalid", reg,123,"TutorialsPoint")
AssertionError: "invalid" does not match 
   "first argument must be string or compiled pattern"
----------------------------------------------------------------------

Junit, el marco de pruebas unitarias de Java (Pyunit es una implementación de JUnit) tiene una práctica opción de tiempo de espera. Si una prueba tarda más del tiempo especificado, se marcará como fallida.

El marco de prueba de Python no contiene ningún soporte para el tiempo de espera. Sin embargo, un módulo de tercera parte llamado timeout-decorator puede hacer el trabajo.

Descargue e instale el módulo desde -

https://pypi.python.org/packages/source/t/timeout-decorator/timeout-decorator-0.3.2.tar.gz

  • Importar timeout_decorator en el código
  • Pon el decorador de tiempo de espera antes de la prueba
  • @timeout_decorator.timeout(10)

Si un método de prueba debajo de esta línea toma más tiempo que el tiempo de espera mencionado (10 minutos) aquí, se generará un TimeOutError. Por ejemplo

import time
import timeout_decorator

class timeoutTest(unittest.TestCase):

   @timeout_decorator.timeout(5)
   def testtimeout(self):
      print "Start"
   for i in range(1,10):
      time.sleep(1)
      print "%d seconds have passed" % i
      
if __name__ == '__main__':
   unittest.main()

unittest2 es un backport de características adicionales agregadas al marco de prueba de Python en Python 2.7 y en adelante. Está probado para ejecutarse en Python 2.6, 2.7 y 3. *. La última versión se puede descargar desdehttps://pypi.python.org/pypi/unittest2

Para usar unittest2 en lugar de unittest, simplemente reemplace import unittest con import unittest2.

Las clases en unittest2 se derivan de las clases apropiadas en unittest, por lo que debería ser posible usar la infraestructura de ejecución de pruebas unittest2 sin tener que cambiar todas las pruebas para usar unittest2 inmediatamente. En caso de que tenga la intención de implementar nuevas funciones, subclasifique su caso de prueba deunittest2.TestCase en lugar de unittest.TestCase

Las siguientes son las nuevas características de unittest2:

  • addCleanups para una mejor gestión de los recursos

  • Contiene muchos métodos nuevos de aserción

  • assertRaises como administrador de contexto, con acceso a la excepción posteriormente

  • Tiene accesorios de nivel de módulo como setUpModule y tearDownModule

  • Incluye load_tests protocolo para cargar pruebas desde módulos o paquetes

  • startTestRun y stopTestRun métodos en TestResult

En Python 2.7, invoca las funciones de la línea de comando unittest (incluido el descubrimiento de prueba) con python -m unittest <args>.

En cambio, unittest2 viene con un script unit2.

unit2 discover
unit2 -v test_module

La opción de línea de comandos -c / - catch para unittest proporciona un manejo más eficiente de control-C durante una ejecución de prueba, junto con la catchbreakparámetro. Con el comportamiento de captura de pausa habilitado, control-C permitirá que se complete la prueba que se está ejecutando actualmente, y la ejecución de la prueba terminará e informará todos los resultados hasta el momento. Un segundo control-c generará un KeyboardInterrupt de la forma habitual.

Si se llama al controlador unittest pero el controlador signal.SIGINT no está instalado, entonces llama al controlador predeterminado. Normalmente, este será el comportamiento esperado por el código que reemplaza un controlador instalado y le delega. Para las pruebas individuales que necesitan el manejo unittest control-c deshabilitado, se puede usar el decorador removeHandler ().

Las siguientes funciones de utilidad habilitan la funcionalidad de manejo de control-c dentro de los marcos de prueba:

unittest.installHandler ()

Instale el controlador control-c. Cuando unasignal.SIGINT se recibe todos los resultados registrados y se llama a TestResult.stop ().

unittest.registerResult (resultado)

Registrar un TestResultobjeto para el manejo de control-c. El registro de un resultado almacena una referencia débil a él, por lo que no evita que el resultado se recolecte como basura.

unittest.removeResult (resultado)

Eliminar un resultado registrado. Una vez que se ha eliminado un resultado, TestResult.stop () ya no se llamará en ese objeto de resultado en respuesta a un control-c.

unittest.removeHandler (función = Ninguna)

Cuando se llama sin argumentos, esta función elimina el controlador control-c si se ha instalado. Esta función también se puede utilizar como decorador de pruebas para eliminar temporalmente el controlador mientras se ejecuta la prueba.

Ejecutor de prueba GUI

El módulo unittest se instala para descubrir y ejecutar pruebas de forma interactiva. Esta utilidad, un script de Python 'inittestgui.py' usa el módulo Tkinter que es un puerto de Python para el kit de herramientas de gráficos TK. Ofrece una GUI fácil de usar para el descubrimiento y la ejecución de pruebas.

Python unittestgui.py

Haga clic en el botón 'Descubrir pruebas'. Aparece un pequeño cuadro de diálogo donde puede seleccionar el directorio y los módulos desde los que se ejecutará la prueba.

Finalmente, haga clic en el botón de inicio. Las pruebas se descubrirán a partir de la ruta seleccionada y los nombres de los módulos, y el panel de resultados mostrará los resultados.

Para ver los detalles de la prueba individual, seleccione y haga clic en prueba en el cuadro de resultados -

Si no encuentra esta utilidad en la instalación de Python, puede obtenerla en la página del proyecto http://pyunit.sourceforge.net/.

Una utilidad similar basada en el kit de herramientas wxpython también está disponible allí.

La distribución estándar de Python contiene el módulo 'Doctest'. La funcionalidad de este módulo permite buscar fragmentos de texto que parecen sesiones interactivas de Python y ejecuta estas sesiones para ver si funcionan exactamente como se muestran.

Doctest puede ser muy útil en los siguientes escenarios:

  • Para verificar que las cadenas de documentación de un módulo estén actualizadas verificando que todos los ejemplos interactivos aún funcionen como se documenta.

  • Para realizar pruebas de regresión verificando que los ejemplos interactivos de un archivo de prueba o un objeto de prueba funcionen como se espera.

  • Para escribir documentación de tutorial para un paquete, ilustrada abundantemente con ejemplos de entrada y salida

En Python, una 'docstring' es una cadena literal que aparece como la primera expresión en una clase, función o módulo. Se ignora cuando se ejecuta la suite, pero el compilador lo reconoce y se coloca en el__doc__atributo de la clase, función o módulo adjunto. Dado que está disponible a través de la introspección, es el lugar canónico para la documentación del objeto.

Es una práctica habitual poner el uso de ejemplo de diferentes partes del código Python dentro de la cadena de documentos. El módulo doctest permite verificar que estas cadenas de documentos estén actualizadas con las revisiones intermitentes en el código.

En el siguiente código, se define una función factorial intercalada con el uso de ejemplo. Para verificar si el uso del ejemplo es correcto, llame a la función testmod () en el módulo doctest.

"""
This is the "example" module.

The example module supplies one function, factorial(). For example,

>>> factorial(5)
120
"""

def factorial(x):
   """Return the factorial of n, an exact integer >= 0.
   >>> factorial(-1)
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
   """
   
   if not x >= 0:
      raise ValueError("x must be >= 0")
   f = 1
   for i in range(1,x+1):
      f = f*i
   return f
   
if __name__ == "__main__":
   import doctest
   doctest.testmod()

Ingrese y guarde el script anterior como FactDocTest.py e intente ejecutar este script desde la línea de comando.

Python FactDocTest.py

No se mostrará ningún resultado a menos que el ejemplo falle. Ahora, cambie la línea de comando a lo siguiente:

Python FactDocTest.py –v

La consola ahora mostrará el siguiente resultado:

C:\Python27>python FactDocTest.py -v
Trying:
   factorial(5)
Expecting:
   120
ok
Trying:
   factorial(-1)
Expecting:
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
ok
2 items passed all tests:
   1 tests in __main__
   1 tests in __main__.factorial
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

Si, por otro lado, el código de la función factorial () no da el resultado esperado en la cadena de documentos, se mostrará el resultado de la falla. Por ejemplo, cambie f = 2 en lugar de f = 1 en el script anterior y vuelva a ejecutar el doctest. El resultado será el siguiente:

Trying:
   factorial(5)
Expecting:
   120
**********************************************************************
File "docfacttest.py", line 6, in __main__
Failed example:
factorial(5)
Expected:
   120
Got:
   240
Trying:
   factorial(-1)
Expecting:
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
ok
1 items passed all tests:
   1 tests in __main__.factorial
**********************************************************************
1 items had failures:
   1 of 1 in __main__
2 tests in 2 items.
1 passed and 1 failed.
***Test Failed*** 1 failures.

Doctest: comprobación de ejemplos en un archivo de texto

Otra aplicación sencilla de doctest es probar ejemplos interactivos en un archivo de texto. Esto se puede hacer con la función testfile ().

El siguiente texto se almacena en un archivo de texto llamado 'ejemplo.txt'.

Using ''factorial''
-------------------
This is an example text file in reStructuredText format. First import
''factorial'' from the ''example'' module:
   >>> from example import factorial
Now use it:
   >>> factorial(5)
   120

El contenido del archivo se trata como una cadena de documentos. Para verificar los ejemplos en el archivo de texto, use la función testfile () del módulo doctest.

def factorial(x):
   if not x >= 0:
      raise ValueError("x must be >= 0")
   f = 1
   for i in range(1,x+1):
      f = f*i
   return f
   
if __name__ == "__main__":
   import doctest
   doctest.testfile("example.txt")
  • Al igual que con testmod (), testfile () no mostrará nada a menos que falle un ejemplo. Si un ejemplo falla, entonces los ejemplos que fallaron y las causas de las fallas se imprimen en la consola, usando el mismo formato que testmod ().

  • En la mayoría de los casos, copiar y pegar de una sesión de consola interactiva funciona bien, pero doctest no intenta hacer una emulación exacta de ningún shell de Python específico.

  • Cualquier salida esperada debe seguir inmediatamente a la línea final '>>>' o '...' que contiene el código, y la salida esperada (si la hay) se extiende a la siguiente línea '>>>' o espacio en blanco.

  • La salida esperada no puede contener una línea de espacios en blanco, ya que dicha línea se toma para señalar el final de la salida esperada. Si la salida esperada contiene una línea en blanco, coloque <BLANKLINE> en su ejemplo de doctest cada lugar donde se espera una línea en blanco.

La API de doctest gira en torno a las siguientes dos clases de contenedor que se utilizan para almacenar ejemplos interactivos de docstrings:

  • Example - Una sola declaración de Python, emparejada con su resultado esperado.

  • DocTest - Una colección de ejemplos, normalmente extraída de una única cadena de documentos o un archivo de texto.

Las siguientes clases de procesamiento adicionales están definidas para buscar, analizar, ejecutar y verificar ejemplos de pruebas de documentación:

  • DocTestFinder - Busca todas las cadenas de documentos en un módulo determinado y utiliza un DocTestParser para crear una prueba de documentos a partir de cada cadena de documentos que contiene ejemplos interactivos.

  • DocTestParser : Crea un objeto doctest a partir de una cadena (como la cadena de documentos de un objeto).

  • DocTestRunner - Ejecuta los ejemplos en un doctest y usa un OutputChecker para verificar su salida.

  • OutputChecker - Compara la salida real de un ejemplo de doctest con la salida esperada y decide si coinciden.

Clase DocTestFinder

Es una clase de procesamiento que se utiliza para extraer las pruebas de documentación que son relevantes para un objeto dado, de su cadena de documentación y las cadenas de documentación de sus objetos contenidos. Actualmente, las pruebas de documentos se pueden extraer de los siguientes tipos de objetos: módulos, funciones, clases, métodos, métodos estáticos, métodos de clase y propiedades.

Esta clase define el método find (). Devuelve una lista de DocTests que están definidos por la cadena de documentos del objeto , o por cualquiera de las cadenas de documentos de sus objetos contenidos.

DocTestParser (clase)

Es una clase de procesamiento que se usa para extraer ejemplos interactivos de una cadena y usarlos para crear un objeto DocTest. Esta clase define los siguientes métodos:

  • get_doctest() - Extraiga todos los ejemplos de pruebas de documentación de la cadena dada y recójalos en un DocTest objeto.

  • get_examples(string[, name]) - Extraiga todos los ejemplos de doctest de la cadena dada y devuélvalos como una lista de Exampleobjetos. Los números de línea están basados ​​en 0. El nombre de argumento opcional es un nombre que identifica esta cadena y solo se usa para mensajes de error.

  • parse(string[, name]) - Divida la cadena dada en ejemplos y texto intermedio, y devuélvalos como una lista de Examplesy cuerdas. Números de línea para elExamplesestán basados ​​en 0. El nombre de argumento opcional es un nombre que identifica esta cadena y solo se usa para mensajes de error.

DocTestRunner (clase)

Esta es una clase de procesamiento que se utiliza para ejecutar y verificar los ejemplos interactivos en un DocTest. En él se definen los siguientes métodos:

report_start ()

Informe que el corredor de pruebas está a punto de procesar el ejemplo dado. Este método se proporciona para permitir subclases deDocTestRunnerpara personalizar su salida; no se debe llamar directamente

report_success ()

Informe que el ejemplo dado se ejecutó correctamente. Este método se proporciona para permitir que las subclases de DocTestRunner personalicen su salida; no debe llamarse directamente.

report_failure ()

Informe que el ejemplo dado falló. Este método se proporciona para permitir subclases deDocTestRunnerpara personalizar su salida; no debe llamarse directamente.

report_unexpected_exception ()

Informe que el ejemplo dado generó una excepción inesperada. Este método se proporciona para permitir que las subclases de DocTestRunner personalicen su salida; no debe llamarse directamente.

ejecutar (prueba)

Ejecutar los ejemplos de prueba (un objeto doctest), y mostrar los resultados utilizando la función de escritor a cabo .

resumir ([detallado])

Imprima un resumen de todos los casos de prueba que ha ejecutado este DocTestRunner y devuelva una tupla con nombre TestResults (fallido, intentado). El argumento detallado opcional controla qué tan detallado es el resumen. Si no se especifica la verbosidad, se utiliza la verbosidad de DocTestRunner.

OutputChecker (clase)

Esta clase se usa para verificar si la salida real de un ejemplo de prueba de documento coincide con la salida esperada.

Los siguientes métodos están definidos en esta clase:

check_output ()

Regreso Truesi el resultado real de un ejemplo ( obtenido ) coincide con el resultado esperado ( deseo ). Siempre se considera que estas cadenas coinciden si son idénticas; pero dependiendo de las banderas de opciones que utilice el ejecutor de pruebas, también son posibles varios tipos de coincidencia no exacta. Consulte la sección Indicadores de opciones y directivas para obtener más información sobre los indicadores de opciones.

diferencia_salida ()

Devuelve una cadena que describe las diferencias entre la salida esperada para un ejemplo dado ( ejemplo ) y la salida real ( obtenida ).

Integración de DocTest con Unittest

El módulo doctest proporciona dos funciones que se pueden utilizar para crear conjuntos de pruebas unittest a partir de módulos y archivos de texto que contienen doctests. Para integrarse con el descubrimiento de prueba unittest, incluya una función load_tests () en su módulo de prueba -

import unittest
import doctest
import doctestexample

def load_tests(loader, tests, ignore):
   tests.addTests(doctest.DocTestSuite(doctestexample))
   return tests

Se formará un TestSuite combinado de pruebas de unittest y doctest y ahora se puede ejecutar mediante el método main () o run () del módulo unittest.

Las siguientes son las dos funciones principales para crear unittest.TestSuite instancias de archivos de texto y módulos con los doctests -

doctest.DocFileSuite ()

Se utiliza para convertir pruebas doctest de uno o más archivos de texto a un unittest.TestSuite. El unittest.TestSuite devuelto debe ser ejecutado por el marco unittest y ejecuta los ejemplos interactivos en cada archivo. Si falla alguno de los ejemplos de un archivo, la prueba unitaria sintetizada falla yfailureException Se genera una excepción que muestra el nombre del archivo que contiene la prueba y un número de línea (a veces aproximado).

doctest.DocTestSuite ()

Se utiliza para convertir las pruebas de doctest de un módulo en un unittest.TestSuite.

El unittest.TestSuite devuelto debe ser ejecutado por el marco unittest y ejecuta cada doctest en el módulo. Si alguna de las pruebas de documentación falla, la prueba unitaria sintetizada falla yfailureException se genera una excepción que muestra el nombre del archivo que contiene la prueba y un número de línea (a veces aproximado)

Bajo las sábanas, DocTestSuite () crea un unittest.TestSuite fuera de las instancias de doctest.DocTestCase, y DocTestCase es una subclase de unittest.TestCase.

De manera similar, DocFileSuite () crea un unittest.TestSuite a partir de instancias de doctest.DocFileCase, y DocFileCase es una subclase de DocTestCase.

Entonces, ambas formas de crear un unittest.TestSuite ejecutan instancias de DocTestCase. Cuando ejecuta las funciones de doctest usted mismo, puede controlar las opciones de doctest en uso directamente, pasando banderas de opciones a las funciones de doctest.

Sin embargo, si está escribiendo un marco unittest, unittest controla en última instancia cuándo y cómo se ejecutan las pruebas. El autor del marco normalmente quiere controlar las opciones de informes de pruebas de documentación (tal vez, por ejemplo, especificadas por las opciones de la línea de comandos), pero no hay forma de pasar las opciones a través de pruebas unitarias a los ejecutores de pruebas de pruebas.

Fue en 2004 que Holger Krekel renombró su stdpaquete, cuyo nombre a menudo se confundía con el de la biblioteca estándar que se envía con Python, con el nombre (solo un poco menos confuso) 'py'. Aunque el paquete contiene varios subpaquetes, ahora se lo conoce casi en su totalidad por su marco py.test.

El marco py.test ha establecido un nuevo estándar para las pruebas de Python y se ha vuelto muy popular entre muchos desarrolladores en la actualidad. Los modismos elegantes y Pythonic que introdujo para la escritura de prueba han hecho posible que las suites de prueba se escriban en un estilo mucho más compacto.

py.test es una alternativa no repetitiva al módulo de prueba de unidad estándar de Python. A pesar de ser una herramienta de prueba extensible y con todas las funciones, cuenta con una sintaxis simple. Crear un conjunto de pruebas es tan fácil como escribir un módulo con un par de funciones.

py.test se ejecuta en todos los sistemas operativos POSIX y WINDOWS (XP / 7/8) con versiones de Python 2.6 y superiores.

Instalación

Utilice el siguiente código para cargar el módulo pytest en la distribución actual de Python, así como una utilidad py.test.exe. Las pruebas se pueden ejecutar con ambos.

pip install pytest

Uso

Simplemente puede utilizar la declaración de aserción para afirmar las expectativas de prueba. La introspección de aserción de pytest informará inteligentemente los valores intermedios de la expresión de aserción, liberándote de la necesidad de aprender los muchos nombresJUnit legacy methods.

# content of test_sample.py
def func(x):
   return x + 1
   
def test_answer():
   assert func(3) == 5

Utilice la siguiente línea de comando para ejecutar la prueba anterior. Una vez que se ejecuta la prueba, el siguiente resultado se muestra en la consola:

C:\Python27>scripts\py.test -v test_sample.py
============================= test session starts =====================
platform win32 -- Python 2.7.9, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- C:\Pyth
on27\python.exe
cachedir: .cache
rootdir: C:\Python27, inifile:
collected 1 items
test_sample.py::test_answer FAILED
================================== FAILURES =====================
_________________________________ test_answer _________________________________
   def test_answer():
>  assert func(3) == 5
E     assert 4 == 5
E     + where 4 = func(3)
test_sample.py:7: AssertionError
========================== 1 failed in 0.05 seconds ====================

La prueba también se puede ejecutar desde la línea de comandos al incluir el módulo pytest usando el interruptor –m.

python -m pytest test_sample.py

Agrupar varias pruebas en una clase

Una vez que comienza a tener más de unas pocas pruebas, a menudo tiene sentido agrupar las pruebas de manera lógica, en clases y módulos. Escribamos una clase que contenga dos pruebas:

class TestClass:
   def test_one(self):
      x = "this"
      assert 'h' in x
   def test_two(self):
      x = "hello"
      assert hasattr(x, 'check')

Se mostrará el siguiente resultado de la prueba:

C:\Python27>scripts\py.test -v test_class.py
============================= test session starts =====================
platform win32 -- Python 2.7.9, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- C:\Pyt
on27\python.exe
cachedir: .cache
rootdir: C:\Python27, inifile:
collected 2 items
test_class.py::TestClass::test_one PASSED
test_class.py::TestClass::test_two FAILED
================================== FAILURES =====================
_____________________________ TestClass.test_two ______________________________
self = <test_class.TestClass instance at 0x01309DA0>

   def test_two(self):
      x = "hello"
>  assert hasattr(x, 'check')
E     assert hasattr('hello', 'check')

test_class.py:7: AssertionError
===================== 1 failed, 1 passed in 0.06 seconds ======================

El proyecto de la nariz se lanzó en 2005, el año siguiente py.testrecibió su apariencia moderna. Fue escrito por Jason Pellerin para admitir los mismos modismos de prueba en los que py.test fue pionero, pero en un paquete que es más fácil de instalar y mantener.

los nose El módulo se puede instalar con la ayuda de la utilidad pip

pip install nose

Esto instalará el módulo nose en la distribución actual de Python, así como un nosetest.exe, lo que significa que la prueba se puede ejecutar con esta utilidad y también con el modificador –m.

C:\python>nosetests –v test_sample.py
Or
C:\python>python –m nose test_sample.py

nose recopila pruebas de unittest.TestCasesubclases, por supuesto. También podemos escribir funciones de prueba simples, así como clases de prueba que no son subclases de unittest.TestCase. nose también proporciona una serie de funciones útiles para escribir pruebas cronometradas, pruebas de excepciones y otros casos de uso comunes.

noserecopila las pruebas automáticamente. No es necesario recopilar manualmente los casos de prueba en conjuntos de pruebas. La ejecución de pruebas responde, ya quenose comienza a ejecutar pruebas tan pronto como se carga el primer módulo de prueba.

Al igual que con el módulo unittest, nose admite accesorios a nivel de paquete, módulo, clase y caso de prueba, por lo que la inicialización costosa se puede realizar con la menor frecuencia posible.

Uso básico

Consideremos que nosetest.py es similar al script utilizado anteriormente:

# content of nosetest.py
def func(x):
   return x + 1
   
def test_answer():
   assert func(3) == 5

Para ejecutar la prueba anterior, use la siguiente sintaxis de línea de comando:

C:\python>nosetests –v nosetest.py

La salida que se muestra en la consola será la siguiente:

nosetest.test_answer ... FAIL
================================================================
FAIL: nosetest.test_answer
----------------------------------------------------------------------
Traceback (most recent call last):
   File "C:\Python34\lib\site-packages\nose\case.py", line 198, in runTest
      self.test(*self.arg)
   File "C:\Python34\nosetest.py", line 6, in test_answer
      assert func(3) == 5
AssertionError
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures = 1)

nose se puede integrar con DocTest usando with-doctest opción en la línea de comando bove.

\nosetests --with-doctest -v nosetest.py

Puedes utilizar nose en un script de prueba -

import nose
nose.main()

Si no desea que el script de prueba salga con 0 en caso de éxito y 1 en caso de error (como unittest.main), use nose.run () en su lugar -

import nose
result = nose.run()

El resultado será verdadero si la ejecución de la prueba es satisfactoria o falso si falla o genera una excepción no detectada.

noseadmite accesorios (métodos de instalación y desmontaje) a nivel de paquete, módulo, clase y prueba. Al igual que con los dispositivos py.test o unittest, la configuración siempre se ejecuta antes de cualquier prueba (o colección de pruebas para paquetes y módulos de prueba); el desmontaje se ejecuta si la instalación se ha completado correctamente, independientemente del estado de la ejecución de prueba.

El módulo nose.tools proporciona una serie de ayudas de prueba que pueden resultarle útiles, incluidos decoradores para restringir el tiempo de ejecución de la prueba y probar las excepciones, y todos los mismos métodos assertX que se encuentran en unittest.TestCase.

  • nose.tools.ok_(expr, msg = None) - Taquigrafía para afirmar.

  • nose.tools.eq_(a, b, msg = None) - Abreviatura de 'aseverar a == b, "% r! =% R"% (a, b)

  • nose.tools.make_decorator(func) - Envuelve un decorador de prueba para replicar correctamente los metadatos de la función decorada, incluidas las cosas adicionales de nose (es decir, configuración y desmontaje).

  • nose.tools.raises(*exceptions) - La prueba debe generar una de las excepciones esperadas para pasar.

  • nose.tools.timed(limit) - La prueba debe terminar dentro del límite de tiempo especificado para pasar

  • nose.tools.istest(func) - Decorador para marcar una función o método como prueba

  • nose.tools.nottest(func) - Decorador para marcar una función o método como no una prueba

Pruebas parametrizadas

El marco de prueba de Python, unittest, no tiene una forma sencilla de ejecutar casos de prueba parametrizados. En otras palabras, no puede pasar argumentos fácilmente a ununittest.TestCase desde afuera.

Sin embargo, los puertos del módulo pytest prueban la parametrización de varias formas bien integradas:

  • pytest.fixture() le permite definir la parametrización a nivel de funciones de luminaria.

  • @pytest.mark.parametrizepermite definir la parametrización a nivel de función o clase. Proporciona múltiples conjuntos de argumentos / accesorios para una función o clase de prueba en particular.

  • pytest_generate_tests permite implementar su propio esquema o extensiones de parametrización dinámica personalizada.

Un módulo de terceros 'con parámetros de nariz' permite realizar pruebas parametrizadas con cualquier marco de prueba de Python. Se puede descargar desde este enlace:https://github.com/wolever/nose-parameterized