unittest unit test skipif run examples example español assertraises python unit-testing

test - En Python, ¿cómo hacer la prueba unitaria en una función sin valor de retorno?



unittest python español (6)

Como se mencionó en otra respuesta, puede usar la biblioteca simulada de Python para hacer afirmaciones sobre las llamadas a funciones / métodos

from mock import patch from my_module import HelloTest import unittest class TestFoo(unittest.TestCase): @patch(''hello.HelloTest.bar'') def test_foo_case(self, mock_bar): ht = HelloTest() ht.foo("some string") self.assertEqual(ob.msg, "SOME STRING") self.assertTrue(mock_bar.called)

Esto soluciona el método de la bar en HelloTest y lo reemplaza con un objeto simulado que registra las llamadas en su contra.

La burla es un poco de un agujero de conejo. Solo hazlo cuando tengas que hacerlo porque hace que tus pruebas sean frágiles. Nunca notará un cambio de API para un objeto simulado, por ejemplo.

Soy un pitón. En estos días me estoy conduciendo para hacer una prueba de unidad más completa en algún módulo central de mi proyecto. Como siempre hacemos una prueba unitaria con los métodos ''assertEqual'', ''assertTrue'', etc., todos estos métodos requieren un valor de retorno de la función que se está probando, me pregunto cómo realizar una prueba unitaria simple en alguna función sin un valor de retorno.

Me gustaría mostrar un pequeño ejemplo aquí, ¿cómo probar la función def foo (self, msg) en HelloTest?

class HelloTest(object): def foo(self, msg): MSG = msg.upper() self.bar(MSG) def bar(self, MSG): print MSG


En Python 3, puede indicar a la print dónde imprimir :

imprimir (* objetos, sep = '''', final = ''/ n'', archivo = sys.stdout, flush = Falso)

Así que agregue un argumento opcional:

def bar(self, MSG, file=sys.stdout): print(MSG, file=file)

En el uso normal, se imprimirá en la salida estándar, pero para las pruebas unitarias puede pasar su propio archivo.

En Python 2 es un poco más desordenado, pero puedes redireccionar stdout a un búfer StringIO :

import StringIO import sys out = StringIO.StringIO() sys.stdout = out # run unit tests sys.stdout = sys.__stdout__ # check the contents of `out`


En este caso particular, me burlaría de la impresión y luego utilizaría el simulacro en mi afirmación.

En Python, usarás el paquete Mock para simularte.


Gracias a la introducción de @Jordan, codifico esto y creo que es una prueba de unidad viable para HelloTest.foo

from mock import Mock import unittest class HelloTestTestCase(unittest.TestCase): def setUp(self): self.hello_test = HelloTest() def tearDown(self): pass def test_foo(self): msg = ''hello'' expected_bar_arg = ''HELLO'' self.hello_test.bar = Mock() self.hello_test.foo(msg) self.hello_test.bar.assert_called_once_with(expected_bar_arg) if __name__ == ''__main__'': unittest.main()


No entiendo muy bien por qué todo el mundo quiere comprobar que la barra de llamadas de Foo.

Foo tiene alguna funcionalidad y esta funcionalidad necesita ser probada. Si foo está usando la barra para hacer esto, no debería ser mi preocupación.

El resultado deseado es que después de llamar a foo(msg) , es que msg.upper() se envía a stdout.

Puede redireccionar la salida estándar a un búfer de cadena y verificar si el contenido de este búfer de cadena coincide con lo que usted espera.

Ejemplo:

import sys import unittest from io import TextIOWrapper, BytesIO class TestScript(unittest.TestCase): def setUp(self): self._old_stdout = sys.stdout sys.stdout = TextIOWrapper(BytesIO(), sys.stdout.encoding) def _output(self): self._stdout.seek(0) return self._stdout.read() def test_foo(self): hello_test = HelloTest() hello_test.foo("blub") self.assertEqual(self._output(), "BLUB") def tearDown(self): sys.stdout = self._old_stdout self._stdout.close()

También puede hacer eso para stdin (y escribir en stdin para simular alguna entrada) y puede subclase TestIOWrapper si necesita hacer algo especial, como permitir que el texto no Unicode se envíe a sys.stdout sin usar sys.stdout.buffer (Python 2 vs. Python 3). Hay un ejemplo para eso en esta respuesta SO . Cuando (aún) usa Python 2 solamente, entonces usar StringIO podría ser mejor que usar el módulo io.


Su código puede ser el que figura a continuación, que realiza la misma tarea que la anterior:

class HelloTest(object): def foo(self, msg): self.msg = msg.upper() self.bar() def bar(self): print self.msg

La prueba unitaria es:

from hello import HelloTest import unittest class TestFoo(unittest.TestCase): def test_foo_case(self): msg = "test" ob = HelloTest() ob.foo(msg) expected = "TEST" self.assertEqual(ob.msg, expected) if __name__ == ''__main__'': unittest.main(exit=False)