In un commento votato alla risposta accettata , Joe chiede:
Esiste un modo per stampare sulla console E acquisire l'output in modo che venga visualizzato nel rapporto junit?
In UNIX, questo è comunemente indicato come tee . Idealmente, il tee anziché l'acquisizione sarebbe l'impostazione predefinita py.test. Non idealmente, né py.test né alcun plug-in py.test di terze parti esistente (... che conosco, comunque ) supporta il tee - nonostante Python supporti banalmente il tee out-of-the-box .
Il py.test di patch delle scimmie per fare qualsiasi cosa non supportata non è banale. Perché? Perché:
- La maggior parte delle funzionalità di py.test è bloccata dietro un
_pytest
pacchetto privato che non deve essere importato esternamente. Tentare di farlo senza sapere cosa stai facendo di solito porta al pytest
pacchetto pubblico a sollevare oscure eccezioni in fase di esecuzione. Grazie mille, py.test. Architettura davvero robusta che ci sei arrivato.
- Anche quando si fa capire come la scimmia-patchare il privato
_pytest
API in modo sicuro, si deve fare in modo prima di eseguire il pubblico pytest
run pacchetto esterno py.test
di comando. Non è possibile farlo in un plug-in (ad esempio, un conftest
modulo di livello superiore nella suite di test). Quando py.test inizia pigramente a importare dinamicamente il tuo plug-in, qualsiasi classe py.test che desideri scimmiottare è stata istanziata da tempo - e non lo hai accesso a quell'istanza. Ciò implica che, se si desidera applicare in modo significativo la patch di scimmia, non è più possibile eseguire in sicurezza il comando esterno . Invece, devi concludere l'esecuzione di quel comando con uno strumento di installazione personalizzato ordini (in ordine):
py.test
test
- Monkey corregge l'
_pytest
API privata .
- Chiama la
pytest.main()
funzione pubblica per eseguire il py.test
comando.
Questa risposta scimmia-patch py.test -s
e --capture=no
opzioni per catturare stderr ma non stdout. Per impostazione predefinita, queste opzioni non catturano né stderr né stdout. Questo non è abbastanza stuzzicante, ovviamente. Ma ogni grande viaggio inizia con un noioso prequel che tutti dimenticano in cinque anni.
Perché farlo Ora te lo dirò. La mia suite di test basata su py.test contiene test funzionali lenti. Visualizzare lo stdout di questi test è utile e rassicurante, impedendo a Leycec di raggiungere killall -9 py.test
quando ancora un altro test funzionale di lunga durata non riesce a fare nulla per settimane. La visualizzazione dello standard di questi test, tuttavia, impedisce a py.test di segnalare traceback delle eccezioni in caso di errori dei test. Che è del tutto inutile. Quindi, costringiamo py.test a catturare stderr ma non stdout.
Prima di arrivare ad essa, questa risposta presuppone che tu abbia già un test
comando setuptools personalizzato che richiama py.test. In caso contrario, consultare la sottosezione Integrazione manuale della pagina Buone Pratiche ben scritta di py.test .
Evitare Non installare pytest-runner , un setuptools di terze parti plug fornendo un setuptools personalizzati test
comandano anche invocando py.test. Se pytest-runner è già installato, probabilmente dovrai disinstallare quel pacchetto pip3 e quindi adottare l'approccio manuale collegato sopra.
Supponendo che tu abbia seguito le istruzioni in Integrazione manuale evidenziate sopra, la tua base di codice dovrebbe ora contenere un PyTest.run_tests()
metodo. Modifica questo metodo per assomigliare:
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)
Per abilitare questa patch scimmia, eseguire py.test come segue:
python setup.py test -a "-s"
Ora verrà catturato Stderr ma non Stdout . Nifty!
L'estensione della suddetta patch di scimmia per stdout e stderr viene lasciata come esercizio al lettore con una canna piena di tempo libero.