postgresql 当 py.test 静默挂起时该怎么办?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26350911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 01:39:21  来源:igfitidea点击:

What to do when a py.test hangs silently?

sqlitepostgresqltimeouthangpytest

提问by Hexatonic

While using py.test, I have some tests that run fine with SQLite but hang silently when I switch to Postgresql. How would I go about debugging something like that? Is there a "verbose" mode I can run my tests in, or set a breakpoint ? More generally, what is the standard plan of attack when pytest stalls silently? I've tried using the pytest-timeout, and ran the test with $ py.test --timeout=300, but the tests still hang with no activity on the screen whatsoever

在使用py.test 时,我有一些测试在 SQLite 上运行良好,但当我切换到 Postgresql 时会静默挂起。我将如何调试类似的东西?是否有“详细”模式可以运行测试或设置断点?更一般地,当pytest静默停顿时,标准的攻击计划是什么?我尝试使用pytest-timeout,并使用 $ py.test --timeout=300 运行测试,但测试仍然挂起,屏幕上没有任何活动

回答by kelaraj

I ran into the same SQLite/Postgres problem with Flask and SQLAlchemy, similar to Gordon Fierce. However, my solution was different. Postgres is strict about table locks and connections, so explicitly closing the session connection on teardown solved the problem for me.

我在使用 Flask 和 SQLAlchemy 时遇到了相同的 SQLite/Postgres 问题,类似于 Gordon Fierce。但是,我的解决方案不同。Postgres 对表锁和连接很严格,所以在拆卸时明确关闭会话连接为我解决了这个问题。

My working code:

我的工作代码:

@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()

Reference: SQLAlchemy

参考:SQLAlchemy

回答by gaoithe

To answer the question "How would I go about debugging something like that?"

回答问题“我将如何调试类似的东西?”

  1. Run with py.test -m trace --trace to get trace of python calls.

  2. One option (useful for any stuck unix binary) is to attach to process using strace -p <PID>. See what system call it might be stuck on or loop of system calls. e.g. stuck calling gettimeofday

  3. For more verbose py.test output install pytest-sugar. pip install pytest-sugarAnd run test with pytest.py --verbose . . .https://pypi.python.org/pypi/pytest-sugar

  1. 使用 py.test -m trace --trace 运行以获取 python 调用的跟踪。

  2. 一种选择(对任何卡住的 unix 二进制文件都很有用)是使用strace -p <PID>. 查看它可能卡在哪个系统调用或系统调用循环上。例如卡住调用 gettimeofday

  3. 要获得更详细的 py.test 输出,请安装 pytest-sugar。pip install pytest-sugar并使用https://pypi.python.org/pypi/pytest-sugar运行测试pytest.py --verbose . . .

回答by Gordon Fierce

I had a similar problem with pytest and Postgresql while testing a Flask app that used SQLAlchemy. It seems pytest has a hard time running a teardown using its request.addfinalizer method with Postgresql.

在测试使用 SQLAlchemy 的 Flask 应用程序时,我在使用 pytest 和 Postgresql 时遇到了类似的问题。pytest 似乎很难使用 Postgresql 的 request.addfinalizer 方法运行拆卸。

Previously I had:

以前我有:

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

    _db.app = app
    _db.create_all()

    request.addfinalizer(teardown)

    return _db

( _db is an instance of SQLAlchemy I import from extensions.py ) But if I drop the database every time the database fixture is called:

( _db 是我从 extensions.py 导入的 SQLAlchemy 的一个实例)但是如果我每次调用数据库夹具时都删除数据库:

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

Then pytest won't hang after your first test.

然后 pytest 在您的第一次测试后不会挂起。

回答by Hexatonic

Not knowing what is breaking in the code, the best way is to isolate the test that is failing and set a breakpoint in it to have a look. Note: I use pudb instead of pdb, because it's really the best way to debug python if you are not using an IDE.

不知道代码中有什么问题,最好的方法是隔离失败的测试并在其中设置断点以查看。注意:我使用 pudb 而不是 pdb,因为如果您不使用 IDE,它确实是调试 Python 的最佳方式。

For example, you can the following in your test file:

例如,您可以在测试文件中执行以下操作:

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

Then run it with

然后运行它

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

Now you'll be able to see exactly where the script locks up, and examine the stack and the database at this particular moment of execution. Otherwise it's like looking for a needle in a haystack.

现在,您将能够准确地看到脚本锁定的位置,并在这个特定的执行时刻检查堆栈和数据库。否则就像大海捞针。

回答by JZ.

In my case the Flask application did not check if __name__ == '__main__':so it executed app.start()when that was not my intention.

在我的情况下,Flask 应用程序没有检查,if __name__ == '__main__':所以它app.start()在不是我的意图时执行。

You can read many more details here.

您可以在此处阅读更多详细信息。