En un comentario votado a la respuesta aceptada , Joe pregunta:
¿Hay alguna forma de imprimir en la consola Y capturar la salida para que se muestre en el informe junit?
En UNIX, esto se conoce comúnmente como teeing . Idealmente, tee en lugar de capturar sería el valor predeterminado de py.test. De forma no ideal, ni py.test ni ningún complemento de py.test de terceros existente (... que yo sepa, de todos modos ) admite el teeing, a pesar de que Python admite trivialmente el tee -out-of-the-box .
Py.test parcheado de mono para hacer cualquier cosa sin soporte no es trivial. ¿Por qué? Porque:
- La mayoría de las funciones de py.test están bloqueadas detrás de un
_pytest
paquete privado que no está destinado a ser importado externamente. Intentar hacerlo sin saber lo que está haciendo generalmente da como resultado que el pytest
paquete público genere oscuras excepciones en tiempo de ejecución. Muchas gracias, py.test. Arquitectura realmente robusta que tienes allí.
- Incluso cuando se hace la manera de mono-privada parchear el
_pytest
API de una manera segura, usted tiene que hacerlo antes de ejecutar el público pytest
ejecute el paquete por el exterior py.test
de comandos. No puede hacer esto en un complemento (por ejemplo, un conftest
módulo de nivel superior en su conjunto de pruebas). En el momento en que py.test perezosamente importa dinámicamente su complemento, cualquier clase de py.test que quería parchear mono hace mucho tiempo que se ha instanciado, y no tiene acceso a esa instancia. Esto implica que, si desea que su parche de mono se aplique de manera significativa, ya no puede ejecutar con seguridad el py.test
comando externo . En cambio, debe ajustar la ejecución de ese comando con herramientas de configuración personalizadastest
comando que (en orden):
- Monkey-parches de la
_pytest
API privada .
- Llama a la
pytest.main()
función pública para ejecutar el py.test
comando.
Esta respuesta mono-parches py.test -s
y --capture=no
opciones para capturar stderr pero no stdout. Por defecto, estas opciones no capturan ni stderr ni stdout. Esto no es del todo bueno, por supuesto. Pero cada gran viaje comienza con una tediosa precuela que todos olvidan en cinco años.
¿Por qué hacer esto? Ahora te lo diré. Mi conjunto de pruebas controladas por py.test contiene pruebas funcionales lentas. Mostrar el stdout de estas pruebas es útil y tranquilizador, evitando que leycec alcance killall -9 py.test
cuando otra prueba funcional de larga duración no puede hacer nada durante semanas. Sin embargo, mostrar el stderr de estas pruebas evita que py.test informe rastreos de excepción en fallas de prueba. Lo cual es completamente inútil. Por lo tanto, obligamos a py.test a capturar stderr pero no stdout.
Antes de llegar a él, esta respuesta asume que ya tiene un test
comando de configuración personalizada que invoca py.test. Si no lo hace, consulte la subsección de Integración manual de la página de Buenas prácticas bien escrita de py.test .
No , no instalar PYtest-corredor , un setuptools terceros plugin de proporcionar un setuptools personalizados test
comando también invocando py.test. Si pytest-runner ya está instalado, probablemente deba desinstalar ese paquete pip3 y luego adoptar el enfoque manual vinculado anteriormente.
Suponiendo que haya seguido las instrucciones en Integración manual resaltadas anteriormente, su base de código ahora debe contener un PyTest.run_tests()
método. Modifique este método para parecerse a:
class PyTest(TestCommand):
.
.
.
def run_tests(self):
# Import the public "pytest" package *BEFORE* the private "_pytest"
# package. While importation order is typically ignorable, imports can
# technically have side effects. Tragicomically, that is the case here.
# Importing the public "pytest" package establishes runtime
# configuration required by submodules of the private "_pytest" package.
# The former *MUST* always be imported before the latter. Failing to do
# so raises obtuse exceptions at runtime... which is bad.
import pytest
from _pytest.capture import CaptureManager, FDCapture, MultiCapture
# If the private method to be monkey-patched no longer exists, py.test
# is either broken or unsupported. In either case, raise an exception.
if not hasattr(CaptureManager, '_getcapture'):
from distutils.errors import DistutilsClassError
raise DistutilsClassError(
'Class "pytest.capture.CaptureManager" method _getcapture() '
'not found. The current version of py.test is either '
'broken (unlikely) or unsupported (likely).'
)
# Old method to be monkey-patched.
_getcapture_old = CaptureManager._getcapture
# New method applying this monkey-patch. Note the use of:
#
# * "out=False", *NOT* capturing stdout.
# * "err=True", capturing stderr.
def _getcapture_new(self, method):
if method == "no":
return MultiCapture(
out=False, err=True, in_=False, Capture=FDCapture)
else:
return _getcapture_old(self, method)
# Replace the old with the new method.
CaptureManager._getcapture = _getcapture_new
# Run py.test with all passed arguments.
errno = pytest.main(self.pytest_args)
sys.exit(errno)
Para habilitar este parche de mono, ejecute py.test de la siguiente manera:
python setup.py test -a "-s"
Ahora se capturará Stderr pero no stdout. ¡Hábil!
Extender el parche de monos anterior a tee stdout y stderr se deja como un ejercicio para el lector con un barril lleno de tiempo libre.