使用登录用户

时间:2017-01-25 12:41:09

标签: python selenium-webdriver flask pytest flask-login

我正在构建一个Flask支持的Web应用程序,其中所有有趣的页面都在登录后面。我想使用Selenium WebDriver对它进行自动化测试。我似乎无法弄清楚如何登录用户并将其与Selenium关联。我尝试的所有内容都会导致Selenium显示“请登录”页面。

不可接受的解决方案1:脚本化的Selenium登录

我见过的许多资源(123以及许多其他资源)建议使用脚本测试手动登录,也就是说将Selenium导航到登录页面,填写表单,然后单击按钮。这是一个可怕的解决方案,原因很多,包括但不限于:

  • 需要在明文处的明文硬编码凭据(我的应用使用社交媒体登录,因此没有可用的测试或伪造凭据)
  • 介绍一个依赖;现在必须在测试或夹具中运行登录例程,并且不能单独运行其他测试
  • 慢;必须在每次测试之前作为浏览器操作运行

不可接受的解决方案2:在Selenium测试运行之前需要手动登录

我可以做的其他事情就是在运行Selenium测试并登录之前打开我自己定位的浏览器。这样可以保留Selenium手中的凭据。问题:

  • PITA;很多时候我会忘记这样做,导致我不得不重新运行测试。因为这是一个麻烦,我可能会更少运行测试套件。
  • 不可扩展;如果我尝试过测试多个浏览器或者在不同的环境中测试,那么这个窗口就是一个选项
  • 慢;仍需要Selenium点击登录页面并点击第三方网站上的“授权应用程序”。

尝试失败的解决方案1:会话伪造

使用类似的东西:

with client.session_transaction() as session:
    session['user_id'] = test_user.id
    session['_fresh'] = True

其中client是app.test_client()的实例。 (这是在pytest夹具中;我正在使用Flask_login)。这允许我在常规单元测试期间登录,但我无法弄清楚如何让Selenium使用同一个会话。

尝试失败的解决方案2:login_user

与上述类似,我可以尝试在灯具中调用Flask_login.login_user(test_user),但我还没有成功地将Selenium与此用户相关联。由于会话已经失败,我唯一能想到的就是在Selenium driver.set_cookie上为这个登录用户设置一个cookie,但我不知道如何从测试客户端或Flask登录中获取一个这样做。

解决方案#3失败:LOGIN_DISABLED

根据Flask-Login docs,您可以在应用配置中设置LOGIN_DISABLED以绕过login_required装饰器。我这样做但我仍然看到登录页面。

我进一步研究了这个问题并不是LOGIN_DISABLED不起作用,而是许多视图依赖于Flask_login的current_user.is_anonymous的行为。如果我要走这条路线,我还需要一个解决方案,以确保current_user设置为测试用户,以便应用程序中的操作与“登录”的用户正确分组。 / p>

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

4 个答案:

答案 0 :(得分:2)

登录后如何获取cookie。可以模拟登录过程,找到您从中获取sid属性以及用户名和密码的字段名称。查看用于存储会话密钥的cookie,假设它是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'])

<强> get_cookie.py

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

尝试在webdriver会话初始化中执行此操作。或者您可以运行它并将此cookie提供给Selenium,例如作为命令行参数(只需使用正确的参数):

Sub DifferenceReport() Dim c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, CellRange As Range Set c1 = Sheets("Difference").Range("G3:G200") Set c2 = Sheets("Difference").Range("H3:H200") Set c3 = Sheets("Difference").Range("K3:K200") Set c4 = Sheets("Difference").Range("N3:N200") Set c5 = Sheets("Difference").Range("Q3:Q200") Set c6 = Sheets("Difference").Range("T3:T200") Set c7 = Sheets("Difference").Range("Z3:Z200") Set c8 = Sheets("Difference").Range("AC3:AC200") Set c9 = Sheets("Difference").Range("AF3:AF200") Set c10 = Sheets("Difference").Range("AI3:AI200") Set CellRange = Union(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) For Each cell In CellRange Select Case cell.Value Case Is = "Same" cell.Interior.ColorIndex = 46 Case Is = "" Case Else End Select Next End Sub

答案 1 :(得分:1)

您可以创建AuthenticatedUser并在测试前将其设为current_user

在我的情况下,我使用了带有Roles的flask-security,因此我还创建并嵌入了一个特定的Role和调用钩子,以便它与flask-principal集成并覆盖在flask-security中发生的用户查找。

由于您似乎没有使用这些额外的库,我会尝试将其重新编写到您的案例中。当您想要禁用登录时,您可以在第一次请求发生之前调用我名为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()

答案 2 :(得分:0)

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

答案 3 :(得分:0)

Cam请您阅读以下链接?

Login using selenium

在此,使用selenium完成登录,并将cookie存储在文件中供以后使用。 之后,您可以使用已保存cookie的请求访问其他页面。