Подтвердить что ты не робот

Что делать, когда py.test висит тихо?

При использовании py.test у меня есть некоторые тесты, которые отлично работают с SQLite, но беспомощно висят, когда я переключаюсь на Postgresql. Как я могу отладить что-то подобное? Есть ли "подробный" режим, в котором я могу выполнить свои тесты или установить точку останова? В более общем плане, каков стандартный план атаки, когда pytest кивает молча? Я пробовал использовать pytest-timeout и запускал тест с $py.test --timeout = 300, но тесты по-прежнему зависают без активности на экране бы то ни было

4b9b3361

Ответ 1

Я столкнулся с той же проблемой SQLite/Postgres, что и Flask и SQLAlchemy, похожей на Gordon Fierce. Однако мое решение было другим. 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: http://docs.sqlalchemy.org/en/rel_0_8/faq.html#my-program-is-hanging-when-i-say-table-drop-metadata-drop-all

Ответ 2

У меня была аналогичная проблема с pytest и Postgresql при тестировании приложения Flask, которое использовало SQLAlchemy. Кажется, что pytest с трудом справляется с использованием метода request.addfinalizer с Postgresql.

Раньше у меня было:

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

    _db.app = app
    _db.create_all()

    request.addfinalizer(teardown)

    return _db

(_db - экземпляр SQLAlchemy, который я импортирую из extensions.py) Но если я удаляю базу данных каждый раз, когда вызывается база данных:

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

Тогда pytest не будет висеть после вашего первого теста.

Ответ 3

Чтобы ответить на вопрос "Как я могу отладить что-то подобное?"

  • Запустите с py.test -m trace -trace, чтобы получить трассировку вызовов python.

  • Один вариант (полезный для любого застрявшего двоичного файла unix) заключается в подключении к процессу с помощью strace -p <PID>. Посмотрите, какой системный вызов он может застрять или цикл системных вызовов. например застрявший вызов gettimeofday

  • Для более подробного вывода py.test установите pytest-sugar. pip install pytest-sugar И запустить тест с помощью pytest.py --verbose . . . https://pypi.python.org/pypi/pytest-sugar

Ответ 4

Не зная, что происходит в коде, лучший способ - изолировать тест, который терпит неудачу, и установить в нем точку останова. Примечание. Я использую pudb вместо pdb, потому что это действительно лучший способ отладки python, если вы не используете IDE.

Например, вы можете в тестовом файле:

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

Теперь вы сможете точно определить, где блокируется script, и изучить стек и базу данных в этот конкретный момент выполнения. В противном случае это похоже на поиск иглы в стоге сена.

Ответ 5

В моем случае приложение Flask не проверило if __name__ == '__main__':, поэтому оно выполнило app.start(), когда это не было моим намерением.

Здесь вы можете прочитать более подробную информацию .