Python 使用登录用户在Flask应用程序上运行Selenium测试

Python 使用登录用户在Flask应用程序上运行Selenium测试,python,selenium-webdriver,flask,pytest,flask-login,Python,Selenium Webdriver,Flask,Pytest,Flask Login,我正在构建一个烧瓶支持的web应用程序,其中所有感兴趣的页面都在登录之后。我想使用SeleniumWebDriver对其运行自动化测试。我似乎不知道如何登录用户并将其与Selenium关联。我尝试的每件事都会导致Selenium显示“请登录”页面 不可接受的解决方案1:脚本化Selenium登录 我看到的许多资源(、、等等)建议使用脚本测试手动登录,也就是说,将Selenium导航到登录页面,填写表单,然后单击按钮。这是一个糟糕的解决方案,原因很多,包括但不限于: 某处需要明文硬编码凭据(我的

我正在构建一个烧瓶支持的web应用程序,其中所有感兴趣的页面都在登录之后。我想使用SeleniumWebDriver对其运行自动化测试。我似乎不知道如何登录用户并将其与Selenium关联。我尝试的每件事都会导致Selenium显示“请登录”页面

不可接受的解决方案1:脚本化Selenium登录 我看到的许多资源(、、等等)建议使用脚本测试手动登录,也就是说,将Selenium导航到登录页面,填写表单,然后单击按钮。这是一个糟糕的解决方案,原因很多,包括但不限于:

  • 某处需要明文硬编码凭据(我的应用程序使用社交媒体登录,因此没有可用的测试或伪造凭据)
  • 引入依赖项;登录例程现在必须在一个测试或装置中运行,其他测试不能与之隔离运行
  • 慢;必须在每次测试之前作为浏览器操作运行
不可接受的解决方案2:在运行Selenium测试之前需要手动登录 在运行Selenium测试并登录之前,我还可以打开针对自己的浏览器。这使Selenium无法获得凭证。问题:

  • 皮塔;很多时候我会忘记这样做,导致我不得不重新运行测试。因为这是一个非常麻烦的问题,我可能会有动力少运行测试套件
  • 不可扩展;如果我曾经尝试测试多个浏览器或在不同的环境中,这是一个很好的选择
  • 慢;仍然需要Selenium点击登录页面并在第三方网站上点击“授权应用程序”
尝试解决方案1失败:会话伪造 使用类似这样的方法:

with client.session_transaction() as session:
    session['user_id'] = test_user.id
    session['_fresh'] = True
其中客户端是
app.test\u client()
的实例。(这是在pytest夹具中;我正在使用Flask_登录)。这允许我在常规的单元测试期间登录,但我还无法弄清楚如何让Selenium使用相同的会话

尝试解决方案2失败:登录\u用户 与上面类似,我可以尝试在fixture中调用
Flask\u login.login\u user(test\u user)
,但我无法成功地将Selenium与此用户关联。由于会话已经失败,我唯一能想到的就是在Selenium
driver.set_cookie
上为这个登录用户设置一个cookie,但我不知道如何从测试客户端或Flask登录中获得一个合适的cookie

失败的解决方案#3:已禁用登录 根据设置,您可以在应用程序配置中设置
LOGIN\u DISABLED
,以绕过
LOGIN\u required
decorator。我这样做了,但我仍然看到一个登录页面

我对此进行了深入研究,问题不在于禁用登录不起作用,而是许多视图取决于Flask\u LOGIN的
当前用户的行为。is\u anonymous
。如果我要走这条路,我还需要一个解决方案来确保
current_user
设置为测试用户,以便应用程序中的操作与“登录”的用户正确分组


如何在不使用Selenium的情况下进行一次身份验证,然后让Selenium在其剩余会话中使用该身份验证用户?

如何在登录后获取Cookie。您可以模拟登录过程,从中找到表单take
action
属性以及用户名和密码字段的名称。查看用于存储会话密钥的cookie,假设它是
sid

获取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'])
尝试在webdriver会话初始化中执行此操作。或者您可以运行它并将此cookie作为命令行参数提供给Selenium(只需使用正确的参数):


selenium--session=$(/get_cookie.py)

我们有一个表单,就像您正在使用的烧瓶一样。我们所做的是在GIT项目中创建一个默认配置文件。然后我把它拉到我的盒子里,用这个默认值创建了我自己的配置文件,并把我的凭证放在这个文件中。它似乎对我们很管用。我使用pydev从Eclipse运行所有测试。我最近开始使用
HTMLTestRunner
来更好地了解结果。我希望这对你有所帮助。

你能阅读下面的链接吗

在这种情况下,登录是使用selenium完成的,cookie存储在一个文件中供以后使用。
然后,您可以使用保存的cookie请求访问其他页面。

您可以创建一个经过身份验证的用户,并在测试之前将其设置为当前用户

在我的例子中,我将flask安全性与角色一起使用,因此我还创建并嵌入了一个特定的角色和调用挂钩,以便它与flask主体集成,并覆盖在flask安全性中发生的用户查找

由于您似乎没有使用这些额外的库,我将尝试将其重新编译到您的案例中。当您想禁用登录时,您可以在第一个请求出现之前调用我命名的
force\u authenticated(app)
。(如果在请求已经发生后调用,则会出错。)

下面是一个完整的、非常简单的、已确认的工作示例:

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

你能为你的Flask服务器的登录页面添加代码和一个简单的测试页面吗?@MaximilianPeters这个登录非常类似,我很确定我用它作为参考。我不知道你所说的简单测试页面是什么意思。您似乎有兴趣向我展示如何让Selenium获取表单元素并执行脚本登录,但这对我来说并不适用(请参阅不可接受的解决方案1)。您能否在使用任何工具登录后提取cookie,然后将其添加到Selenium中?另一种变体:Se不尝试填写表单,而是发布到硬编码URL硬编码值以获取会话cookie。@EugeneLisitsky我考虑过cookie提取,但不知道如何使用此设置获取有效的cookie。将其作为
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()