web-dev-qa-db-ja.com

py.testがサイレントにハングしたときに何をすべきか?

py.test を使用しているときに、SQLiteで正常に実行されますが、Postgresqlに切り替えると何も表示されずにハングするテストがあります。そのようなものをデバッグするにはどうすればよいですか?テストを実行したり、ブレークポイントを設定したりできる「詳細」モードはありますか?より一般的には、pytestがサイレントストールする場合の標準的な攻撃計画は何ですか? pytest-timeout を使用してみましたが、$ py.test --timeout = 300を使用してテストを実行しましたが、画面に何も表示されず、テストがハングします

26
Hexatonic

FlaskとSQLAlchemyを使用して、Gordon Fierceと同様に、同じSQLite/Postgresの問題に遭遇しました。ただし、私の解決策は異なりました。Postgresはテーブルのロックと接続に関して厳密であるため、セッション接続を明示的に閉じますティアダウンで私のために問題を解決しました。

私の作業コード:

@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

16
kelaraj

SQLAlchemyを使用するFlaskアプリをテストしているときに、pytestとPostgresqlで同様の問題が発生しました。pytestは、Postgresqlでrequest.addfinalizerメソッドを使用してティアダウンを実行するのに苦労しているようです。

以前私は持っていました:

@pytest.fixture
def db(app, request):
    def teardown():
        _db.drop_all()

    _db.app = app
    _db.create_all()

    request.addfinalizer(teardown)

    return _db

(_dbは、extensions.pyからインポートするSQLAlchemyのインスタンスです)しかし、データベースフィクスチャが呼び出されるたびにデータベースをドロップすると、次のようになります。

@pytest.fixture
def db(app, request):
    _db.app = app
    _db.drop_all()
    _db.create_all()
    return _db

そうすれば、最初のテストの後でpytestがハングしなくなります。

5
Gordon Fierce

「そのようなものをデバッグするにはどうすればいいですか?」という質問に答えるために。

  1. py.test -m trace --traceで実行して、python呼び出しのトレースを取得します。

  2. 1つのオプション(スタックされたUNIXバイナリに役立つ)は、strace -p <PID>を使用してプロセスにアタッチすることです。スタックしているシステムコールまたはシステムコールのループを確認します。例えばgettimeofdayの呼び出しでスタック

  3. より詳細なpy.test出力については、pytest-sugarをインストールしてください。 pip install pytest-sugarそしてpytest.py --verbose . . .でテストを実行 https://pypi.python.org/pypi/pytest-sugar

4
gaoithe

私の場合、Flaskアプリケーションは_if __name__ == '__main__':_をチェックしなかったので、意図しないときにapp.start()を実行しました。

より多くの詳細を読むことができます ここ

0
JZ.

コードで何が壊れているのかわからない場合、最善の方法は、失敗しているテストを分離し、ブレークポイントを設定して確認することです。注:IDEを使用していない場合は、pythonをデバッグするための最良の方法なので、pdbではなくpudbを使用します。

たとえば、テストファイルで次のことができます。

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. 
    ...

次にそれを実行します

py.test -s --capture=no test_my_stuff.py

これで、スクリプトがどこにロックアップするかを正確に確認し、この特定の実行時にスタックとデータベースを調べることができます。そうでなければ、干し草の山から針を探すようなものです。

0
Hexatonic