¿Es posible que una prueba unitaria afirme que un método llama a sys.exit ()

Respuestas:

155

Si. sys.exitaumenta SystemExit, para que puedas comprobarlo con assertRaises:

with self.assertRaises(SystemExit):
    your_method()

Las instancias de SystemExittienen un atributo codeque se establece en el estado de salida propuesto, y el administrador de contexto devuelto por assertRaisestiene la instancia de excepción capturada como exception, por lo que verificar el estado de salida es fácil:

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

Documentación de sys.exit :

Salir de Python. Esto se implementa levantando la SystemExitexcepción ... es posible interceptar el intento de salida en un nivel externo.

Pavel Anossov
fuente
3
+1, excepto que si quiere verificar que llama sys.exit(1)(a diferencia de, digamos, sys.exit(0)) debes afirmar que codees 1. ¿Supongo que podrías hacer eso con assertRaisesRegexp(SystemExit, '1')?
abarnert
Estaba seguro de que había un unittestmétodo que le permite pasar una excepción y un predicado invocable para ejecutar en la excepción o sus argumentos, en lugar de solo un patrón de expresión regular para ejecutar en la representación de cadena de su primer argumento ... pero supongo que no. ¿Hay algún otro módulo de prueba en el que esté pensando?
abarnert
1
+1, en cuanto a verificar el código de error, es mucho más sencillo: self.assertRaisesRegex( SystemExit, '^2$', testMethod ) Menos código, lo suficientemente legible.
Marek Lewandowski
1
@MarekLewandowski: error tipográfico. Debe serself.assertRaisesRegexp
Evgen
12

Aquí hay un ejemplo de trabajo completo. A pesar de la excelente respuesta de Pavel, me tomó un tiempo darme cuenta de esto, así que lo incluyo aquí con la esperanza de que sea útil.

import unittest
from glf.logtype.grinder.mapping_reader import MapReader

INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"

class TestMapReader(unittest.TestCase):

    def test_get_tx_names_incomplete_mapping_file(self):
        map_reader = MapReader()
        with self.assertRaises(SystemExit) as cm:
            tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
        self.assertEqual(cm.exception.code, 1)
Oso travis
fuente
3

Encontré la respuesta a su pregunta en la búsqueda de documentación de pruebas unitarias de Python para "Prueba de excepciones". Usando su ejemplo, la prueba unitaria se vería así:

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

Recuerde incluir todos los argumentos necesarios para probar su función.

Sleepykyle
fuente
1

Como nota adicional a la excelente respuesta de Pavel, también puede verificar estados específicos si se proporcionan en la función que está probando. Por ejemplo, si your_method()contiene lo siguiente sys.exit("Error"), sería posible realizar una prueba de "Error" específicamente:

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")
sustrato binario
fuente