Unit test сеанс фляжи - не может воспроизвести сбой с session_transaction
Я тестирую приложение Flask (Flask 0.9), и, в частности, у меня есть сеансовое устройство, которое я хотел бы запустить документированным способом, будучи чем-то вроде этого (как я понимаю):
from flask import Flask, session
app = Flask(__name__)
@app.route('/', methods=['POST'])
def m():
logging.error(session) # expect {'x': 1}
return ""
with app.test_request_context() as trc:
with app.test_client() as c:
with c.session_transaction() as sess:
sess['x'] = 1
c.post()
Это работает так, как ожидалось, причем вывод выглядит примерно так:
ERROR:root:<SecureCookieSession {'x': 1}>
К сожалению, я столкнулся с неожиданным результатом, когда данные сеанса не установлены в функции конечной точки, то есть вывод выглядит примерно так:
ERROR:root:<SecureCookieSession {}>
Эта проблема проявляется только при запуске из моей модульной системы тестирования. Как бы то ни было, я не могу воспроизвести эту проблему с дегенеративным случаем, хотя я сделал довольно значительные усилия с сущностью некоторых из этих усилий здесь. Главным моментом является то, что я включил itsdangerous
и Google App Engine testbed
, ожидая, что, возможно, одна из них была причиной.
В моей собственной системе я пошел дальше, чем сущность, и почти полностью реплицировал мою инфраструктуру unit test, пытаясь ее изолировать. Аналогичным образом, я удалил все увеличивающиеся количества соответствующего кода из моей системы тестирования. К моменту, я не могу думать о различиях между вырожденным случаем и моей урезанной структурой, которая могла бы повлиять на результат. Я прошел через вызов c.post()
в pdb, чтобы попытаться выяснить причину этой злости, но еще не получил полезной информации.
Что бы все сказать, я был бы благодарен за небольшое руководство или предложение относительно того, где может быть проблема. Что может повлиять на контекст Werkzeug таким образом, что session_transaction
не соблюдается?
Ответы
Ответ 1
Вот что я сделал:
# Code that modifies the current `session`; we must be in a test context already.
headers = {}
with self.client.session_transaction():
# Get the cookie that is sent to the browser to establish a connection
# via a fake request.
response = make_response()
self.app.session_interface.save_session(self.app, session, response)
headers['Cookie'] = response.headers.get('Set-Cookie', '')
self.client.post(..., headers=headers) # also works for .get, .put, etc.
Ответ 2
В моем случае я автоматически удалял файлы cookie в определенный домен, загружая файл конфигурации. Обновляя конфигурацию "на лету", я смог получить файлы cookie для работы во время модульного тестирования. Установив для свойства SESSION_COOKIE_DOMAIN
значение None
, все домены (а именно localhost) могли устанавливать сеансы.
app.config.update(
SESSION_COOKIE_DOMAIN = None
)
Возможно, вы захотите поиграть с настройками конфигурации, описанными в Обработка конфигурации в документах.
Ответ 3
Я ненавижу воскресить старый вопрос, но я считаю, что я решил решение этой проблемы. Для тестирования попробуйте установить для своего сервера имя localhost
:
app.config['SERVER_NAME'] = 'localhost'
Я изначально использовал Brian hack, но это решило проблему для меня.
Ответ 4
Без тестового теста, который на самом деле терпит неудачу, трудно сказать много чего. Все, о чем я могу думать, это то, что экземпляр TestClient
, который вы используете, делает запрос отличным от того, который вы используете для настройки сеанса. Например. вы можете сделать gist неудачным, как ожидалось, с этим:
with self.app.test_client() as c:
with c.session_transaction() as sess:
sess['d'] = 1
self.client.post()
Но поскольку это не тот случай или сущность, идите фигуру.