Durante l'utilizzo di py.test, ho alcuni test che funzionano bene con SQLite ma che si bloccano silenziosamente quando passo a Postgresql. Come faccio a fare il debug di qualcosa del genere? Esiste una modalità "verbose" in cui posso eseguire i miei test o impostare un breakpoint? Più in generale, qual è il piano di attacco standard quando pytest si blocca in silenzio? Ho provato a utilizzare il pytest-timeout e ho eseguito il test con $ py.test --timeout = 300, ma i test sono ancora bloccati senza attività sullo schermo di qualsiasi tipoCosa fare quando un py.test si blocca silenziosamente?
risposta
Non sapendo cosa si sta rompendo nel codice, il migliore il modo è isolare il test che sta fallendo e impostare un punto di interruzione in esso per dare un'occhiata. Nota: uso pudb invece di pdb, perché è davvero il modo migliore per eseguire il debug di python se non si utilizza un IDE.
Ad esempio, è possibile quanto segue nel file di prova:
import pudb
...
def test_create_product(session):
pudb.set_trace()
# Create the Product instance
# Create a Price instance
# Add the Product instance to the session.
...
Poi eseguirlo con
py.test -s --capture=no test_my_stuff.py
Ora sarete in grado di vedere esattamente dove lo script si blocca, e esaminare lo stack e il database in questo particolare momento di esecuzione. Altrimenti è come cercare un ago in un pagliaio.
Ho avuto un problema simile con pytest e Postgresql durante il test di un'app Flask che utilizzava SQLAlchemy. Sembra che pytest abbia difficoltà a eseguire un teardown usando il suo metodo request.addfinalizer con Postgresql.
precedenza avevo:
@pytest.fixture
def db(app, request):
def teardown():
_db.drop_all()
_db.app = app
_db.create_all()
request.addfinalizer(teardown)
return _db
(_db è un'istanza di SQLAlchemy importare da extensions.py) Ma se lascio cadere il database ogni volta che il dispositivo di database si chiama:
@pytest.fixture
def db(app, request):
_db.app = app
_db.drop_all()
_db.create_all()
return _db
Quindi pytest non si bloccherà dopo il primo test.
Aveva lo stesso problema con Flask, pytest e factory-boy. La soluzione sopra ha risolto il problema. – Burnash
Ho incontrato lo stesso problema SQLite/Postgres con Flask e SQLAlchemy, simile a Gordon Fierce. Tuttavia, la mia soluzione era diversa. Postgres è rigido riguardo ai blocchi e alle connessioni delle tabelle, quindi chiudere esplicitamente la connessione della sessione su teardown ha risolto il problema per me.
Il mio codice di lavoro:
@pytest.yield_fixture(scope='function')
def db(app):
# app is an instance of a flask app, _db a SQLAlchemy DB
_db.app = app
with app.app_context():
_db.create_all()
yield _db
# Explicitly close DB connection
_db.session.close()
_db.drop_all()
SQLAlchemy di riferimento: "Come potrei fare per il debug di una cosa del genere" http://docs.sqlalchemy.org/en/rel_0_8/faq.html#my-program-is-hanging-when-i-say-table-drop-metadata-drop-all
La nuova posizione del riferimento SQLAlchemy è qui ora: http://docs.sqlalchemy.org/en/latest/faq/metadata_schema.html#my-program-is-hanging-when-i-say-table-drop- metadati-drop-tutto – Mani
Per rispondere alla domanda
Run con py.test --trace traccia -m per ottenere traccia di chiamate pitone.
Un'opzione (utile per qualsiasi binario unix bloccato) deve essere allegata al processo utilizzando
strace -p <PID>
. Scopri a quale sistema potrebbe essere bloccato o il ciclo di chiamate di sistema. per esempio. bloccato chiamando gettimeofdayPer ulteriori dettagli di output py.test installare pytest-sugar.Test
pip install pytest-sugar
e correre conpytest.py --verbose . . .
https://pypi.python.org/pypi/pytest-sugar
Nel mio caso l'applicazione Flask non ha controllato if __name__ == '__main__':
quindi eseguito app.start()
quando non era mia intenzione.
È possibile leggere molti altri dettagli here.
Cercherei una sorta di funzionalità di timeout - Non so se una cosa del genere è integrata in py.test ... –
Sono contento che l'abbiate portato, perché ho dimenticato di menzionare ho installato il modulo pytest-timeout e l'ho impostato per scadere dopo 6 secondi, ma i test sono ancora bloccati indefinitamente. – Hexatonic
Hai provato entrambi i metodi di timeout 'thread' e' signal'? Entrambi si appendono allo stesso modo? Sei stato in grado di isolare un particolare test che si blocca su PostgreSQL ma non su SQLite? –