Python 的蝗虫:UI 上没有显示蝗虫统计数据
Locust with Python: No Locust Stats are showing on UI
我是 Locust(和 Python)的新手,正在尝试对 API 进行负载测试。我的 Locust UI 没有显示任何统计数据 - 没有用户孵化,没有 API 调用等。我需要帮助弄清楚如何让它们出现在 UI 上,这样我才能得到统计数据。
这是我的 locust.py 文件:
from locust import HttpUser, SequentialTaskSet, task, constant
import finops_service.locust_files.finops_fx_load_testing as load_test
class FXTransaction(SequentialTaskSet):
def __init__(self, parent):
super().__init__(parent)
self.comp_data = dict()
self.rate_lock_response = dict()
self.transaction_response = dict()
self.fx_providerID = '57638f08-e938-48d7-accf-325b6728a9ee'
self.headers = {"Content-Type": "application/json"}
def on_start(self):
load_test.login(self),
@task
def get_company_data(self):
# Get company data
self.comp_data = load_test.get_company_data(self)
print("Company is: ", self.comp_data['company'])
print("Vendor is: ", self.comp_data['vendor'])
print("Payment Method is: ", self.comp_data['payment_method'])
print("Funding Method is: ", self.comp_data['funding_method'])
# @task
# def rate_lock(self):
print("Starting rate lock")
load_test.rate_lock(self)
print("This is the returned rate lock response:")
print(self.rate_lock_response)
# @task
# def approve_transaction(self):
# print("Starting transaction")
# load_test.approve_transaction(self)
# print("This is the returned transaction response:")
# print(self.transaction_response)
class MyUser(HttpUser):
wait_time = constant(1)
# weight = 1
host = "http://localhost:8080/PaymentService/base/"
tasks = [FXTransaction]
这是我的功能:
import json
import random
import uuid
from utils import json_util as json_util
enter code here
def login(self):
try:
with self.client.post(
"security/login",
headers={'Content-Type': 'application/json',
'Authorization': 'BASIC 0ee89b88-5c4b-4922-b1f9-c1584ab26e7e:12345'},
name=login,
timeout=55.6,
catch_response=True) as response:
if response.status_code != 200:
response.failure("Login failed")
else:
response.success()
print("Login succeeded")
self.headers.update({'if-Match': "{}".format(response.headers["ETag"])})
except ConnectionRefusedError:
print("The test could not connect to {}".format("http://localhost:8080/PaymentService/security/login"))
raise
def get_company_data(self):
comp_index = random.randrange(0, 9)
print("Random company data index is: ", comp_index)
try:
body = json.load(open("finops_service/locust_files/load_testing_data.json", 'r'))
comp_data = body['fx']['multipleCompanies_10']['company_data'][comp_index]
except ConnectionRefusedError:
print("The test could not connect to {}".format("http://localhost:8080/PaymentService/security/login"))
raise
return comp_data
def rate_lock(self):
body = json_util.get_json_object(
"/finops_service/locust_files/rate_lock_load_testing.json",
'fx'.lower(),
'valid_multiple_20'.lower()
)
body["debtorCompanyProfileId"] = self.comp_data['company']
i = 0
# there are 20 rate locks so need to update each request
while i < 20:
body["rateRequestPayments"][i]["creditorProfileId"] = self.comp_data['vendor']
body["rateRequestPayments"][i]["debtorProfileId"] = self.comp_data['company']
body["rateRequestPayments"][i]["paymentMethodId"] = self.comp_data['payment_method']
random_float_no = round(random.uniform(1.11, 999.99), 2)
body['rateRequestPayments'][i]['amount'] = random_float_no
i += 1
try:
print("RIGHT BEFORE RATE LOCK CALL")
with self.client.post("services/transaction/fx/rate/lock",
data=json.dumps(body),
headers=self.headers,
name="rate lock",
timeout=55.6,
catch_response=True) as response:
if "GENERIC_FAILURE" in response.text:
response.failure("FAIL")
print("Rate lock call failed")
else:
response.success()
print("rate lock succeeded")
print("Rate lock response is:.........", response)
print("Rate lock response TEXT is:.........", response.text)
self.rate_lock_response = response.text
except ConnectionRefusedError:
print("The test could not connect to {}".format(
"http://localhost:8080/PaymentService/services/transaction/fx/rate/lock"))
raise
当我 运行 这样做时,我可以看到 self.client.post("services/transaction/fx/rate/lock"... 正在发生并且成功或失败。但是,在 Locust UI,我显示 0 个用户孵化(控制台显示我孵化 5 个)和 0 个任务。
我每次 运行 都会收到这个错误,它看起来与我的统计数据没有显示有关,但我不知道为什么会这样:
Traceback (most recent call last):
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/gevent/pywsgi.py", line 999, in handle_one_response
self.run_application()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/gevent/pywsgi.py", line 945, in run_application
self.result = self.application(self.environ, self.start_response)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/web.py", line 319, in wrapper
return view_func(*args, **kwargs)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/util/cache.py", line 21, in wrapper
cache["result"] = func(*args, **kwargs)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/web.py", line 208, in request_stats
"safe_name": escape(s.name, quote=False),
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/html/__init__.py", line 19, in escape
s = s.replace("&", "&") # Must be done first!
AttributeError: 'function' object has no attribute 'replace'
2021-03-18T16:44:29Z {'REMOTE_ADDR': '::1', 'REMOTE_PORT': '49242', 'HTTP_HOST': 'localhost:8089', (hidden keys: 25)} failed with AttributeError
有人可以帮我弄清楚如何显示我的统计信息吗?
谢谢!!!!
Locust 中未显示的统计信息是因为您发布的异常。如果您解决了这个问题并顺利到达您的代码运行的位置,您应该会在 Locust UI.
中看到统计信息
您的代码存在一些问题。
我不确定将您的代码粘贴到 SO 中是否只是一个问题,但是您的 on_start()
和 get_company_data()
函数(以及 @task
装饰器)需要缩进所以他们是 FXTransaction
.
的一部分
此外,尝试在 login()
或 get_company_data()
中使用 self.client
是行不通的,因为它们不是 class 的一部分,所以没有这样的事情 self
。您可能希望将该函数中的 self
更改为 client
,然后在从 on_start()
函数调用它时传入 self.client
。
但是您的主要问题可能在这里:
with self.client.post(
"security/login",
headers={'Content-Type': 'application/json',
'Authorization': 'BASIC 0ee89b88-5c4b-4922-b1f9-c1584ab26e7e:12345'},
name=login,
…
name
这是您要访问的端点 (URL) 的名称。这应该是一个字符串,但你给它你的函数 login
。因此,当 Locust 代码试图用你的 name
值做一些它想做的事情时,期望它是一个字符串,它会失败,因为它试图在一个函数上做这些事情。这就是 AttributeError: 'function' object has no attribute 'replace'
的意思。
我认为如果你解决所有这些问题,Locust 应该可以工作。
我是 Locust(和 Python)的新手,正在尝试对 API 进行负载测试。我的 Locust UI 没有显示任何统计数据 - 没有用户孵化,没有 API 调用等。我需要帮助弄清楚如何让它们出现在 UI 上,这样我才能得到统计数据。
这是我的 locust.py 文件:
from locust import HttpUser, SequentialTaskSet, task, constant
import finops_service.locust_files.finops_fx_load_testing as load_test
class FXTransaction(SequentialTaskSet):
def __init__(self, parent):
super().__init__(parent)
self.comp_data = dict()
self.rate_lock_response = dict()
self.transaction_response = dict()
self.fx_providerID = '57638f08-e938-48d7-accf-325b6728a9ee'
self.headers = {"Content-Type": "application/json"}
def on_start(self):
load_test.login(self),
@task
def get_company_data(self):
# Get company data
self.comp_data = load_test.get_company_data(self)
print("Company is: ", self.comp_data['company'])
print("Vendor is: ", self.comp_data['vendor'])
print("Payment Method is: ", self.comp_data['payment_method'])
print("Funding Method is: ", self.comp_data['funding_method'])
# @task
# def rate_lock(self):
print("Starting rate lock")
load_test.rate_lock(self)
print("This is the returned rate lock response:")
print(self.rate_lock_response)
# @task
# def approve_transaction(self):
# print("Starting transaction")
# load_test.approve_transaction(self)
# print("This is the returned transaction response:")
# print(self.transaction_response)
class MyUser(HttpUser):
wait_time = constant(1)
# weight = 1
host = "http://localhost:8080/PaymentService/base/"
tasks = [FXTransaction]
这是我的功能:
import json
import random
import uuid
from utils import json_util as json_util
enter code here
def login(self):
try:
with self.client.post(
"security/login",
headers={'Content-Type': 'application/json',
'Authorization': 'BASIC 0ee89b88-5c4b-4922-b1f9-c1584ab26e7e:12345'},
name=login,
timeout=55.6,
catch_response=True) as response:
if response.status_code != 200:
response.failure("Login failed")
else:
response.success()
print("Login succeeded")
self.headers.update({'if-Match': "{}".format(response.headers["ETag"])})
except ConnectionRefusedError:
print("The test could not connect to {}".format("http://localhost:8080/PaymentService/security/login"))
raise
def get_company_data(self):
comp_index = random.randrange(0, 9)
print("Random company data index is: ", comp_index)
try:
body = json.load(open("finops_service/locust_files/load_testing_data.json", 'r'))
comp_data = body['fx']['multipleCompanies_10']['company_data'][comp_index]
except ConnectionRefusedError:
print("The test could not connect to {}".format("http://localhost:8080/PaymentService/security/login"))
raise
return comp_data
def rate_lock(self):
body = json_util.get_json_object(
"/finops_service/locust_files/rate_lock_load_testing.json",
'fx'.lower(),
'valid_multiple_20'.lower()
)
body["debtorCompanyProfileId"] = self.comp_data['company']
i = 0
# there are 20 rate locks so need to update each request
while i < 20:
body["rateRequestPayments"][i]["creditorProfileId"] = self.comp_data['vendor']
body["rateRequestPayments"][i]["debtorProfileId"] = self.comp_data['company']
body["rateRequestPayments"][i]["paymentMethodId"] = self.comp_data['payment_method']
random_float_no = round(random.uniform(1.11, 999.99), 2)
body['rateRequestPayments'][i]['amount'] = random_float_no
i += 1
try:
print("RIGHT BEFORE RATE LOCK CALL")
with self.client.post("services/transaction/fx/rate/lock",
data=json.dumps(body),
headers=self.headers,
name="rate lock",
timeout=55.6,
catch_response=True) as response:
if "GENERIC_FAILURE" in response.text:
response.failure("FAIL")
print("Rate lock call failed")
else:
response.success()
print("rate lock succeeded")
print("Rate lock response is:.........", response)
print("Rate lock response TEXT is:.........", response.text)
self.rate_lock_response = response.text
except ConnectionRefusedError:
print("The test could not connect to {}".format(
"http://localhost:8080/PaymentService/services/transaction/fx/rate/lock"))
raise
当我 运行 这样做时,我可以看到 self.client.post("services/transaction/fx/rate/lock"... 正在发生并且成功或失败。但是,在 Locust UI,我显示 0 个用户孵化(控制台显示我孵化 5 个)和 0 个任务。
我每次 运行 都会收到这个错误,它看起来与我的统计数据没有显示有关,但我不知道为什么会这样:
Traceback (most recent call last):
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/gevent/pywsgi.py", line 999, in handle_one_response
self.run_application()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/gevent/pywsgi.py", line 945, in run_application
self.result = self.application(self.environ, self.start_response)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/web.py", line 319, in wrapper
return view_func(*args, **kwargs)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/util/cache.py", line 21, in wrapper
cache["result"] = func(*args, **kwargs)
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/site-packages/locust/web.py", line 208, in request_stats
"safe_name": escape(s.name, quote=False),
File "/Users/michellegautier/.pyenv/versions/3.7.4/lib/python3.7/html/__init__.py", line 19, in escape
s = s.replace("&", "&") # Must be done first!
AttributeError: 'function' object has no attribute 'replace'
2021-03-18T16:44:29Z {'REMOTE_ADDR': '::1', 'REMOTE_PORT': '49242', 'HTTP_HOST': 'localhost:8089', (hidden keys: 25)} failed with AttributeError
有人可以帮我弄清楚如何显示我的统计信息吗?
谢谢!!!!
Locust 中未显示的统计信息是因为您发布的异常。如果您解决了这个问题并顺利到达您的代码运行的位置,您应该会在 Locust UI.
中看到统计信息您的代码存在一些问题。
我不确定将您的代码粘贴到 SO 中是否只是一个问题,但是您的 on_start()
和 get_company_data()
函数(以及 @task
装饰器)需要缩进所以他们是 FXTransaction
.
此外,尝试在 login()
或 get_company_data()
中使用 self.client
是行不通的,因为它们不是 class 的一部分,所以没有这样的事情 self
。您可能希望将该函数中的 self
更改为 client
,然后在从 on_start()
函数调用它时传入 self.client
。
但是您的主要问题可能在这里:
with self.client.post(
"security/login",
headers={'Content-Type': 'application/json',
'Authorization': 'BASIC 0ee89b88-5c4b-4922-b1f9-c1584ab26e7e:12345'},
name=login,
…
name
这是您要访问的端点 (URL) 的名称。这应该是一个字符串,但你给它你的函数 login
。因此,当 Locust 代码试图用你的 name
值做一些它想做的事情时,期望它是一个字符串,它会失败,因为它试图在一个函数上做这些事情。这就是 AttributeError: 'function' object has no attribute 'replace'
的意思。
我认为如果你解决所有这些问题,Locust 应该可以工作。