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
_pytestpacchetto privato che non deve essere importato esternamente. Tentare di farlo senza sapere cosa stai facendo di solito porta al pytestpacchetto 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
_pytestAPI in modo sicuro, si deve fare in modo prima di eseguire il pubblico pytestrun pacchetto esterno py.testdi comando. Non è possibile farlo in un plug-in (ad esempio, un conftestmodulo 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.testtest
- Monkey corregge l'
_pytestAPI privata .
- Chiama la
pytest.main()funzione pubblica per eseguire il py.testcomando.
Questa risposta scimmia-patch py.test -se --capture=noopzioni 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.testquando 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 testcomando 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 testcomandano 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.