Установка follow_redirects = True приводит к тайм-ауту pytest при применении колбы

#python #flask #pytest

Вопрос:

У меня есть приложение для колбы, которое я пытаюсь протестировать.

Прямо сейчас у меня есть тест, который работает правильно, когда я проверяю код состояния http 302, но когда я добавляю, follow_redirects = True я не получаю ответа от pytest при его запуске, и я не уверен, почему.

Вот класс тестов, которые я пытаюсь выполнить:

 class TestEmailResetToken():

    def test_email_reset(self, client, auth):

        auth.login()
        token    = 'misshapentoken4856'
        response = client.get(f'/confirm/{token}', follow_redirects = True)
        assert response.status_code == 200
        assert b'Update Your Signin Credentials' in response.data

    def test_email_reset_valid_auth(self, app, client, auth):

        token_data = {
            'new_email': 'newemail@gmail.com',
            'current_email': 'myemail@gmail.com'
        }

        with app.app_context():
            token = generate_new_email_token(**token_data)

        auth.login()
        response = client.get(f'/confirm/{token}', follow_redirects = True)
        assert response.status_code == 200
        assert b'Email updated successfully' in response.data

        with app.app_context():
            email = confirm_token(token)
            user  = User.query.filter_by(email = email['new']).first()

        assert user.email == email['new']


    def test_email_reset_invalid_auth(self, app, client, auth):

        token_data = {
            'new_email': 'newemail@gmail.com',
            'current_email': 'foo@bar.com'
        }

        with app.app_context():
            token = generate_new_email_token(**token_data)

        auth.login()
        response = client.get(f'/confirm/{token}', follow_redirects = True)
        assert response.status_code == 200
        assert b'There was a problem processing your request' in response.data
 

Моя проблема в том, что test_email_reset_invalid_auth удаление follow_redirects опции приводит к завершению теста, но когда она есть, тест просто зависает.

Более того, если я прокомментирую тест выше test_email_reset_valid_auth , то он будет работать просто отлично. Поэтому я предполагаю, что это связано с тем, как я настроил свой набор тестов, а не с самим модульным тестом.

Если это поможет, вот содержимое моего conftest.py файла:

 from app import create_app
from app.commands import init_db
from app.extensions import db as _db
from app.blueprints.user.models import User
from app.blueprints.user import extras

@pytest.fixture(scope='session')
def app():
    """Starts up a version of the application in testing mode to use for further tests"""

    params = {
        'DEBUG': False,
        'TESTING': True,
        'WTF_CSRF_ENABLED': False,
        'SQLALCHEMY_DATABASE_URI': settings.SQLALCHEMY_TEST_DATABASE_URI
    }

    _app = create_app(settings_override=params)


    with _app.app_context():

        _db.drop_all()
        _db.create_all()

        # users with different settings for testing
        test_users = [{
            'email': 'myemail@gmail.com',
            'password': 'Passw0rd!',
            'sec_question': 'What is your favorite band?',
            'sec_answer': 'built to spill'
        },{
            'email': 'myemail1@hotmail.com',
            'password': 'Passw0rd!',
            'sec_question': 'What is your favorite band?',
            'sec_answer': 'Built to Spill',
            'active': True
        }]

        for user_params in test_users:

            user = User(**user_params)
            _db.session.add(user)
            _db.session.commit()

    yield _app

@pytest.fixture(scope='function')
def client(app):
    """Yields a test version of the application"""
    return app.test_client()

@pytest.fixture(scope='function')
def runner(app):
    """Yields a test version of the app to test command line functions"""
    return app.test_cli_runner()

class Authentication():
    """Allows other test objects to login / logout"""
    def __init__(self, client):
        self._client = client

    def login(self, email='myemail@gmail.com', password = 'Passw0rd!', follow_redirects=True):
        return self._client.post('/login', data = {'email': email, 'password': password}, follow_redirects = follow_redirects)

    def logout(self, follow_redirects = True):
        return self._client.get('/logout', follow_redirects = follow_redirects)

@pytest.fixture(scope='function')
def auth(client):
    return Authentication(client)