Python 中的 Locust 负载测试:需要登录网站,有什么建议吗?

问题描述 投票:0回答:2

有一个本地主机网站需要负载测试(我们称之为

https://localhost/hompeage
)。但是,要访问需要负载测试的网站,我必须通过公司登录页面登录(我们称之为
https://vpn.company.com/login
)。每次都需要此登录并且不会保存。

Python 中的 Selenium 工作

现在我知道登录 vi Selenium 的正确顺序,包括 Web 元素 ID。请参阅下面的 Python 文件(它用作我的功能测试用例的

__init__
):

网站.py

import sys
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

class Website:
    def __init__(self, browser: str, username: str, password: str):
        try:
            if browser == "Chrome":
                self.driver = webdriver.Chrome()
            elif browser == "Edge":
                self.driver = webdriver.Edge()
        except:
            print("Only 'Chrome' and 'Edge' browsers are supported for testing.")
            sys.exit(1)
        
        self.driver.get("https://localhost/homepage")
        
        get_source = self.driver.page_source # Scan the page
        not_private1 = "Your connection is not private"
        not_private2 = "Your connection isn't private"
        if (not_private1 in get_source or not_private2 in get_source):
            # NET::ERR_CERT_COMMON_NAME_INVALID
            self.driver.find_element(By.ID, "details-button").click() # Click "Advanced" button
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # Scroll to the bottom of the page
            self.driver.find_element(By.ID, "proceed-link").click() # Click "Proceed to localhost (unsafe)" link
        
        get_source = self.driver.page_source # Redirects to Corporate Login Page
        login_page = "Login Page"
        if (login_page in get_source):
            self.driver.find_element(By.ID, "userNameInput").send_keys(username)
            self.driver.find_element(By.ID, "passwordInput").send_keys(password)
            self.driver.find_element(By.ID, "submitButton").click()
            time.sleep(1)

      # connects to the homepage
    
    def close(self):
        self.driver.close() # Closes the browser

(通过直接连接到

https://vpn.company.com/login
而不是通过
"Your connection isn't private"
片段,上面的方法可能会更有效,无论如何,这只会将我带到
https://vpn.company.com/login
页面)

Locust:“登录”方法

至于 Locust,我已经意识到我不能使用 Selenium,我必须依赖 Locust 特定的 Python 代码(我已经尝试将

__init__
代码放入
def on_start
中)。这是迄今为止我的 Locust 文件:

蝗虫.py

import time
import webbrowser

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    # HttpUser is the User Agent who can visit different endpoints
    wait_time = between(1, 5) # How long it takes visiting an endpoint before it starts visiting another one
    
    def on_start(self):
        login_page = "https://vpn.company.com/login"
        self.client.get(login_page)

        post_data = {"usernameInput":"TestUser", "passwordInput":"Test123", "Submit":"submitButton"}
        self.client.post(login_page, post_data)
        time.sleep(1)
    
    @task
    def landing_page(self):
        self.client.get(url="/")
    
    #@task
    #def about_page(self):
    #    self.client.get(url="/#about")
    
    # Connect to Locust Page (in new tab, if possible)
    webbrowser.open("http://localhost:8089", new = 2)

"Submit":"submitButton"
正确吗?至少我记得看到过一个
self.client.post
的例子,其中在CSS元素ID之前包含
Submit

Locust 测试:“登录”方法

要运行此测试,我在终端中运行以下命令:

locust -f locust.py --host https://localhost/homepage --users 5 --spawn-rate 20

结果

这是我运行

locust
命令时的输出:

C:\Users\Adam\eclipse-workspace\TestProject4>locust -f libraries\\locust.py --host https://localhost/homepage --users 5 --spawn-rate 20
[2023-05-24 10:39:16,812] vm-w10/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all netwo
rk interfaces)
[2023-05-24 10:39:16,830] vm-w10/INFO/locust.main: Starting Locust 2.15.1
[2023-05-24 10:39:20,907] vm-w10/INFO/locust.runners: Ramping to 5 users at a rate of 20.00 per second
[2023-05-24 10:39:20,910] vm-w10/INFO/locust.runners: All users spawned: {"WebsiteUser": 5} (5 total users)

在 Locust Web 应用程序中,我得到以下结果:

类型 姓名 #请求 #失败
获取 /主页/ 13 13
获取 /登录 5 0
发帖 /登录 10 0

由此,我可以假设最初的

GET
连接到
https://vpn.company.com/login
,并且
POST
maybe 正确吗?显然主页的
GET
未连接。我想“也许是身份验证和连接到网站之间的延迟?”所以我添加了
time.sleep(1)
但这并没有改变 Locust 返回的结果(甚至不确定 Locust 是否识别
time.sleep
)。

如果我在终端中

CTRL + C
,我会得到以下信息:

Traceback (most recent call last):
  File "C:\Users\Adam\AppData\Local\Programs\Python\Python311\Lib\site-packages\gevent\_ffi\loop.py", line 270, in python_check_callback
    def python_check_callback(self, watcher_ptr): # pylint:disable=unused-argument

KeyboardInterrupt
2023-05-24T14:42:14Z
[2023-05-24 10:42:14,476] vm-w10/INFO/locust.main: Shutting down (exit code 1)
Type     Name                                                         # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|-----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
GET      /homepage/                                                        13  13(100.00%) |     22      18      37     21 |    1.76        1.76
GET      /login
       5     0(0.00%) |    300 
    204     506    260 |    0.68        0.00
POST     /login
       5     0(0.00%) |     71 
     59      77     75 |    0.68        0.00
--------|-----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                                                       23   13(56.52%) |     93      18     506     37 |    3.11        1.76

Response time percentiles (approximated)
Type     Name                                                                 50%    66%    75%    80%    90%    95%    98%    99%  99.9% 99.99
Error report
# occurrences      Error
------------------|----------------------------------------------------------------------------------------------------------------------------
13                 GET /homepage/: SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certific
ate (_ssl.c:1002)')
------------------|----------------------------------------------------------------------------------------------------------------------------

Locust:“Cookie”方法

管理员建议我尝试使用 Cookie(他还告诉我,登录方法“可能”是通过 SAML 令牌,但他并不完全确定)。因此,我在登录页面后找到了我认为是 Cookie 的内容,而不是登录。我更新了我的代码,因此它使用 Cookie 作为令牌(不确定我这样做是否正确):

蝗虫.py

import time import webbrowser from locust import HttpUser, task, between class WebsiteUser(HttpUser): # HttpUser is the User Agent who can visit different endpoints wait_time = between(1, 5) # How long it takes visiting an endpoint before it starts visiting another one def on_start(self): login_page = "https://vpn.company.com/login" self.client.get(login_page) cookie = ".AspNetCore.Cookies=CfDJ8MTHe7hMbp5IvzCac79rZkiG3Tb_tarAITryM-FPR2oZzF5wGHBAVTqIKaIGSOGQZ_CkAeD0M0wOXmRuL0cgRpY6da6K5Ftpod0Ygj3BVxI2ybu5VNUY_RhLGpLuiWI-4BwJKBGtpE1MKhIoB0uq0amGMHFM4jeSYh_TeR21aHWkVXLjmLvT_q_PqNbqIXubK7hHaAk5lwa0pEJ8mZYZE5ZHM-vYL7iid-vWI8IWVLieLIALGOsKEp7W0GHX1cHT2-y_F4O7xBuRidl41xMjGc3V6RLRzrQ1LGFSRwrvNIWksa5IyW-8GtMIIYmNClIPtVgJEgunwWrnwdu3odr28F3bQabc2VPGtk3mW-3QgarNUJxAkGuAM943bUdFKPHyCj6L-2LJGL9EANBWg0Do6wSGy-iXoFb_1aHhzybgzZqy7Cj6xmG_jCDZNWm1sUXySW6meE9BMa2IcG_DZc-kdMsBYOXDn8rw0SHoRlIOwVlVIgOxv13lqMJbHjCp4cEuNwcuqMCWNkX6QB5eFTeqr78fo2g1b90jQfQIi5fD0rs0rMw3m38FMtOBo1Mx0fYNpyQu0iP7FjoWzW37LtxXZCrZtd1lQwv8SbJtcdsz2Q9RQtMq7v-9PXj33uuvRgZtMFApCi0pUSsjM6eeP2cOHKx-woMrGdfGcsdyMzjgHB5ioMpZyqyTmsxjyZmTrGN2Mc_eixGRZnQi0SmQwcZSuCJzirseFzE440UcjXEZbW6Xgt-oMPQes_6VWRLR6fYqB4Cp7Nuzoxgd2RcRHfd7p6uvGTp5nX66oXom-8dsZRRXiagFNUcQPTXplJ8JVPPIip1-T_9jd_JWVLVMxv2ROfh4ftZu0hgzRdrtKJITCnBqzLHzw9BZa0WJabayvdWZMlbhQsJ2RwI4vDIf-uMBMLaSs--iKurKr3AVpgsGRVwYtEs2ZnhGIQDSFSbb4ZPXtz4KZb5pRneZwenGdbuDMMy83sMZHdZ7BHq1vRg7cq2khRVCatUZ467kBaCgKVucjE8TlxKs9t4XvsrQXYgf63zZZf1SNPt1bP-c1E9gNWODoWSLn999Apx_TfusjNY4zCoPMo8ZvrZzZx4UEKeEjiZY-F9k0z873f373wWhdd9QaEpGQiZzhk6fyrvaMjifhN4JLLOKPVOzOsNadRSkJnPRzBzZokmOzybVNc0gkcVp9pfUbcvSHePgazxpSn6Iw4JhN-m0Dj8PAfLGQwqoDLgNCzyNp35x8kBzP-ONbdL1EJbicf9en5ypRmD4oH7QXxVXuigecJnDlvZz4n-aB4D" self.client.post(login_page, {"token": cookie}) time.sleep(1) @task def landing_page(self): self.client.get(url="/") #@task #def about_page(self): # self.client.get(url="/#about") # Connect to Locust Page (in new tab, if possible) webbrowser.open("http://localhost:8089", new = 2)

Locust 测试:“Cookie”方法

与“登录”方法结果完全相同。因此,要么我正确执行了两种身份验证方法,但它只是无法识别主页(我对此表示怀疑),或者我执行的“登录”和“Cookie”方法都不正确。

终极问题

我做错了什么?

我更喜欢使用“登录”方法(我假设问题与“登录”按钮有关),但任何登录方法都可以使用 GET 表示

https://localhost/hompeage 
在 Locust 中不返回任何失败,所以我对其他想法持开放态度。
    

python authentication selenium-webdriver load-testing locust
2个回答
0
投票

我追求 SAML 令牌路由(“Cookies”方法)是正确的,但我需要的不仅仅是 Cookies。我需要复制

cURL (bash)

代码(右键单击 -> Inspect 页面 -> 在

DevTools
, Network -> 右键单击
GET 200
标题 9 成功登录) ->
Copy 
->
Copy as cURL (bash)
),将该代码转换为 Python(应包括
cookies
headers
),然后包含 Cookie 和标头作为
self.client.post
登录方法。这不是最简单的过程,但幸运的是它完成了!

这是我更新的代码。

我计划制作 cookies

headers
正确的全局变量,我可以在未来的所有
@task
中引用。
on_start
不再需要。
    


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.