Запустите Selenium Tests в приложении Flask с зарегистрированным пользователем
Я создаю веб-приложение на основе Flask, где все интересные страницы находятся за логином. Я хотел бы запустить автоматические тесты против него с помощью Selenium WebDriver. Я не могу понять, как войти в систему пользователя и связать его с Selenium. Все, что я пробую, приводит к тому, что Selenium представлен на странице "Пожалуйста, войдите".
Недопустимое решение 1: Сценарий входа в систему Selenium
Многие из ресурсов, которые я видел ( 1, 2, 3, среди многих других), предлагают вручную войти в систему с помощью скриптового теста, то есть навигации Selenium к странице входа в систему, заполнения форм и нажатия кнопок. Это ужасное решение по многим причинам, включая, но не ограничиваясь:
- Требуется жесткое кодирование учетных данных в виде открытого текста (мое приложение использует вход в социальные сети, поэтому нет доступных тестовых или готовых учетных данных)
- Вводит зависимость; подпрограмма входа в систему должна теперь выполняться в тесте или в приборе, и никакие другие тесты не могут выполняться отдельно от нее
- Медленный; должен быть запущен перед каждым тестом как действие браузера
Неприемлемое решение 2. Требуется ручной вход перед запуском тестов Selenium
Что-то еще, что я мог сделать, это открыть браузер, на который я нацеливался, прежде чем запускать тесты Selenium, и войти в систему. Это держит учетные данные в руках Selenium. Проблемы:
- PITA; Много раз я забуду это сделать, и мне придется заново запускать тесты. Из-за таких хлопот у меня может возникнуть желание меньше запускать набор тестов.
- Не масштабируется; если я когда-либо пытался протестировать несколько браузеров или в другой среде, это прямо в окне, как вариант
- Медленный; по-прежнему требуется, чтобы Selenium щелкнул страницу входа и нажал "Авторизовать приложение" на стороннем сайте.
Неудачная попытка решения 1: Подделка сессии
Используя что-то вроде этого:
with client.session_transaction() as session:
session['user_id'] = test_user.id
session['_fresh'] = True
где клиент является экземпляром app.test_client()
, (Это в приспособлении pytest; я использую Flask_login). Это позволяет мне входить в систему во время регулярных юнит-тестов, но я не смог выяснить, как заставить Selenium использовать этот же сеанс.
Неудачная попытка решения 2: login_user
Как и выше, я могу попробовать позвонить Flask_login.login_user(test_user)
в приспособлении, но мне не удалось связать Selenium с этим пользователем. Поскольку сессия уже не удалась, единственное, что я мог подумать, это установить cookie для этого авторизованного пользователя в Selenium. driver.set_cookie
, но я понятия не имею, как получить для этого подходящий тестовый клиент или Flask.
Неудачное решение № 3: LOGIN_DISABLED
В соответствии с документами Flask-Login вы можете установить LOGIN_DISABLED
в конфигурации вашего приложения, чтобы обойти login_required
декоратор. Я сделал это, но я все еще вижу страницу входа.
Я углубился в это немного больше, и проблема не в том, что LOGIN_DISABLED не работает, а в том, что многие представления зависят от поведения Flask_login. current_user.is_anonymous
, Если бы я собирался пойти по этому пути, мне также нужно решение, чтобы убедиться, что current_user
устанавливается для тестового пользователя, чтобы действия в приложении были правильно сгруппированы с пользователем, вошедшим в систему.
Как выполнить аутентификацию один раз без использования Selenium, а затем заставить Selenium использовать этого аутентифицированного пользователя до конца сеанса?
4 ответа
Как получить куки после входа в систему. Можно смоделировать процесс входа в систему, найти форму action
атрибут из него и имена полей для имени пользователя и пароля. Посмотрите, что cookie используется для хранения ключа сеанса, предположим, что это sid
,
get_cookie.py:
import requests
r = requests.post(action,
data={'login': 'your_username', 'password': 'You_p@ssw0rd'},
allow_redirects=False)
# now r.cookies contains all returned cookies,
# print cookie you need:
print(r.cookie['sid'])
Попробуйте сделать это при инициализации сеанса вебдрайвера. Или вы можете запустить его и передать этот файл cookie в Selenium, например, в качестве параметра командной строки (просто используйте правильные параметры):
selenium .... --session=$(./get_cookie.py)
Cam, пожалуйста, прочитайте следующую ссылку?
При этом вход в систему осуществляется с использованием селена, а файл cookie сохраняется в файле для последующего использования. И после этого вы можете использовать запросы с сохраненным куки для доступа к другим страницам.
Вы можете создать AuthenticatedUser и сделать его current_user
до испытаний.
В моем случае я использую безопасность флеш-памяти с ролями, поэтому я также создаю и внедряю определенную роль и ловушки вызовов, чтобы она интегрировалась с принципалом фляги и переопределяла пользовательский поиск, который происходит в безопасности фляги.
Поскольку вы, по-видимому, не используете эти дополнительные библиотеки, я постараюсь перенастроить их на ваш случай. Когда вы хотите отключить вход в систему, вы бы назвали то, что я назвал force_authenticated(app)
до того, как ваш первый запрос происходит. (Это будет ошибка, если вызвано после того, как запросы уже произошли.)
# This is a non-anonymous, authenticated user
class AuthenticatedUser(flask_login.UserMixin):
def get_id(self):
return 'TestUser'
def force_authenticated(app):
@app.before_request
def set_identity():
user = AuthenticatedUser()
flask_login.login_user(user)
Вот полный, действительно минимальный, подтвержденный работающий пример:
from flask import Flask
import flask_login
class AuthenticatedUser(flask_login.UserMixin):
def get_id(self):
return 'TestUser'
def force_authenticated(app):
@app.before_request
def set_identity():
user = AuthenticatedUser()
flask_login.login_user(user)
app = Flask(__name__)
app.secret_key = 'blahblah'
lm = flask_login.LoginManager(app)
lm.init_app(app)
force_authenticated(app)
@app.route('/')
@flask_login.login_required
def hello_world():
return 'Hello, World!'
app.run()
У нас есть форма, такая же, как вы используете колбу. Мы создали файл конфигурации по умолчанию в проекте GIT. Затем я перенес это в свою коробку и создал свой собственный файл конфигурации из этого значения по умолчанию и поместил свои учетные данные в этот файл. Кажется, у нас это хорошо работает. Я запускаю все свои тесты из Eclipse, используя pydev. Я недавно начал использовать HTMLTestRunner
чтобы получить лучшую картину результатов. Я надеюсь, что это помогает вам.