mirror of
https://github.com/httprunner/httprunner.git
synced 2026-08-28 03:30:01 +08:00
feat: make locusts as httprunner plugin
This commit is contained in:
@@ -283,31 +283,3 @@ class HttpRunner(object):
|
|||||||
""" get test reuslt summary.
|
""" get test reuslt summary.
|
||||||
"""
|
"""
|
||||||
return self._summary
|
return self._summary
|
||||||
|
|
||||||
|
|
||||||
def prepare_locust_tests(path):
|
|
||||||
""" prepare locust testcases
|
|
||||||
|
|
||||||
Args:
|
|
||||||
path (str): testcase file path.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: locust tests data
|
|
||||||
|
|
||||||
[
|
|
||||||
testcase1_dict,
|
|
||||||
testcase2_dict
|
|
||||||
]
|
|
||||||
|
|
||||||
"""
|
|
||||||
tests_mapping = loader.load_tests(path)
|
|
||||||
testcases = parser.parse_tests(tests_mapping)
|
|
||||||
|
|
||||||
locust_tests = []
|
|
||||||
|
|
||||||
for testcase in testcases:
|
|
||||||
testcase_weight = testcase.get("config", {}).pop("weight", 1)
|
|
||||||
for _ in range(testcase_weight):
|
|
||||||
locust_tests.append(testcase)
|
|
||||||
|
|
||||||
return locust_tests
|
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# locusts
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
$ locusts -f xxx.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
$ python3 -m plugins.locusts
|
||||||
|
|
||||||
|
Usage: locust [options] [LocustClass [LocustClass2 ... ]]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-H HOST, --host=HOST Host to load test in the following format:
|
||||||
|
http://10.21.32.33
|
||||||
|
--web-host=WEB_HOST Host to bind the web interface to. Defaults to '' (all
|
||||||
|
interfaces)
|
||||||
|
-P PORT, --port=PORT, --web-port=PORT
|
||||||
|
Port on which to run web host
|
||||||
|
-f LOCUSTFILE, --locustfile=LOCUSTFILE
|
||||||
|
Python module file to import, e.g. '../other.py'.
|
||||||
|
Default: locustfile
|
||||||
|
--csv=CSVFILEBASE, --csv-base-name=CSVFILEBASE
|
||||||
|
Store current request stats to files in CSV format.
|
||||||
|
--master Set locust to run in distributed mode with this
|
||||||
|
process as master
|
||||||
|
--slave Set locust to run in distributed mode with this
|
||||||
|
process as slave
|
||||||
|
--master-host=MASTER_HOST
|
||||||
|
Host or IP address of locust master for distributed
|
||||||
|
load testing. Only used when running with --slave.
|
||||||
|
Defaults to 127.0.0.1.
|
||||||
|
--master-port=MASTER_PORT
|
||||||
|
The port to connect to that is used by the locust
|
||||||
|
master for distributed load testing. Only used when
|
||||||
|
running with --slave. Defaults to 5557. Note that
|
||||||
|
slaves will also connect to the master node on this
|
||||||
|
port + 1.
|
||||||
|
--master-bind-host=MASTER_BIND_HOST
|
||||||
|
Interfaces (hostname, ip) that locust master should
|
||||||
|
bind to. Only used when running with --master.
|
||||||
|
Defaults to * (all available interfaces).
|
||||||
|
--master-bind-port=MASTER_BIND_PORT
|
||||||
|
Port that locust master should bind to. Only used when
|
||||||
|
running with --master. Defaults to 5557. Note that
|
||||||
|
Locust will also use this port + 1, so by default the
|
||||||
|
master node will bind to 5557 and 5558.
|
||||||
|
--heartbeat-liveness=HEARTBEAT_LIVENESS
|
||||||
|
set number of seconds before failed heartbeat from
|
||||||
|
slave
|
||||||
|
--heartbeat-interval=HEARTBEAT_INTERVAL
|
||||||
|
set number of seconds delay between slave heartbeats
|
||||||
|
to master
|
||||||
|
--expect-slaves=EXPECT_SLAVES
|
||||||
|
How many slaves master should expect to connect before
|
||||||
|
starting the test (only when --no-web used).
|
||||||
|
--no-web Disable the web interface, and instead start running
|
||||||
|
the test immediately. Requires -c and -r to be
|
||||||
|
specified.
|
||||||
|
-c NUM_CLIENTS, --clients=NUM_CLIENTS
|
||||||
|
Number of concurrent Locust users. Only used together
|
||||||
|
with --no-web
|
||||||
|
-r HATCH_RATE, --hatch-rate=HATCH_RATE
|
||||||
|
The rate per second in which clients are spawned. Only
|
||||||
|
used together with --no-web
|
||||||
|
-t RUN_TIME, --run-time=RUN_TIME
|
||||||
|
Stop after the specified amount of time, e.g. (300s,
|
||||||
|
20m, 3h, 1h30m, etc.). Only used together with --no-
|
||||||
|
web
|
||||||
|
-L LOGLEVEL, --loglevel=LOGLEVEL
|
||||||
|
Choose between DEBUG/INFO/WARNING/ERROR/CRITICAL.
|
||||||
|
Default is INFO.
|
||||||
|
--logfile=LOGFILE Path to log file. If not set, log will go to
|
||||||
|
stdout/stderr
|
||||||
|
--print-stats Print stats in the console
|
||||||
|
--only-summary Only print the summary stats
|
||||||
|
--no-reset-stats [DEPRECATED] Do not reset statistics once hatching has
|
||||||
|
been completed. This is now the default behavior. See
|
||||||
|
--reset-stats to disable
|
||||||
|
--reset-stats Reset statistics once hatching has been completed.
|
||||||
|
Should be set on both master and slaves when running
|
||||||
|
in distributed mode
|
||||||
|
-l, --list Show list of possible locust classes and exit
|
||||||
|
--show-task-ratio print table of the locust classes' task execution
|
||||||
|
ratio
|
||||||
|
--show-task-ratio-json
|
||||||
|
print json data of the locust classes' task execution
|
||||||
|
ratio
|
||||||
|
-V, --version show program's version number and exit
|
||||||
|
--exit-code-on-error=EXIT_CODE_ON_ERROR
|
||||||
|
sets the exit code to post on error
|
||||||
|
```
|
||||||
|
|
||||||
|
## tests
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
$ python -m plugins.locusts.test_main
|
||||||
|
```
|
||||||
@@ -15,7 +15,7 @@ import multiprocessing
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from httprunner import logger
|
from httprunner import logger, loader, parser
|
||||||
|
|
||||||
|
|
||||||
def parse_locustfile(file_path):
|
def parse_locustfile(file_path):
|
||||||
@@ -46,7 +46,6 @@ def gen_locustfile(testcase_file_path):
|
|||||||
locustfile_path = 'locustfile.py'
|
locustfile_path = 'locustfile.py'
|
||||||
template_path = os.path.join(
|
template_path = os.path.join(
|
||||||
os.path.dirname(os.path.realpath(__file__)),
|
os.path.dirname(os.path.realpath(__file__)),
|
||||||
"templates",
|
|
||||||
"locustfile_template"
|
"locustfile_template"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -168,5 +167,29 @@ def main():
|
|||||||
start_locust_main()
|
start_locust_main()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def prepare_locust_tests(path):
|
||||||
main()
|
""" prepare locust testcases
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str): testcase file path.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: locust tests data
|
||||||
|
|
||||||
|
[
|
||||||
|
testcase1_dict,
|
||||||
|
testcase2_dict
|
||||||
|
]
|
||||||
|
|
||||||
|
"""
|
||||||
|
tests_mapping = loader.load_tests(path)
|
||||||
|
testcases = parser.parse_tests(tests_mapping)
|
||||||
|
|
||||||
|
locust_tests = []
|
||||||
|
|
||||||
|
for testcase in testcases:
|
||||||
|
testcase_weight = testcase.get("config", {}).pop("weight", 1)
|
||||||
|
for _ in range(testcase_weight):
|
||||||
|
locust_tests.append(testcase)
|
||||||
|
|
||||||
|
return locust_tests
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
from httprunner.plugins.locusts import main
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+4
-4
@@ -1,13 +1,13 @@
|
|||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import zmq
|
|
||||||
from httprunner.exceptions import MyBaseError, MyBaseFailure
|
|
||||||
from httprunner.api import prepare_locust_tests
|
|
||||||
from httprunner.runner import Runner
|
|
||||||
from locust import HttpLocust, TaskSet, task
|
from locust import HttpLocust, TaskSet, task
|
||||||
from locust.events import request_failure
|
from locust.events import request_failure
|
||||||
|
|
||||||
|
from httprunner.exceptions import MyBaseError, MyBaseFailure
|
||||||
|
from httprunner.runner import Runner
|
||||||
|
from httprunner.plugins.locusts import prepare_locust_tests
|
||||||
|
|
||||||
logging.getLogger().setLevel(logging.CRITICAL)
|
logging.getLogger().setLevel(logging.CRITICAL)
|
||||||
logging.getLogger('locust.main').setLevel(logging.INFO)
|
logging.getLogger('locust.main').setLevel(logging.INFO)
|
||||||
logging.getLogger('locust.runners').setLevel(logging.INFO)
|
logging.getLogger('locust.runners').setLevel(logging.INFO)
|
||||||
+1
-1
@@ -42,7 +42,7 @@ contextlib2 = "^0.5.5"
|
|||||||
hrun = "httprunner.cli:main"
|
hrun = "httprunner.cli:main"
|
||||||
ate = "httprunner.cli:main"
|
ate = "httprunner.cli:main"
|
||||||
httprunner = "httprunner.cli:main"
|
httprunner = "httprunner.cli:main"
|
||||||
locusts = "httprunner.locusts:main"
|
locusts = "httprunner.plugins.locusts:main"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry>=0.12"]
|
requires = ["poetry>=0.12"]
|
||||||
|
|||||||
+1
-17
@@ -2,10 +2,9 @@ import os
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
import unittest
|
|
||||||
|
|
||||||
from httprunner import exceptions, loader, parser
|
from httprunner import exceptions, loader, parser
|
||||||
from httprunner.api import HttpRunner, prepare_locust_tests
|
from httprunner.api import HttpRunner
|
||||||
from tests.api_server import HTTPBIN_SERVER
|
from tests.api_server import HTTPBIN_SERVER
|
||||||
from tests.base import ApiServerUnittest
|
from tests.base import ApiServerUnittest
|
||||||
|
|
||||||
@@ -788,18 +787,3 @@ class TestApi(ApiServerUnittest):
|
|||||||
results.records[1]["name"],
|
results.records[1]["name"],
|
||||||
"create user and check result."
|
"create user and check result."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestLocust(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_prepare_locust_tests(self):
|
|
||||||
path = os.path.join(
|
|
||||||
os.getcwd(), 'tests/locust_tests/demo_locusts.yml')
|
|
||||||
locust_tests = prepare_locust_tests(path)
|
|
||||||
self.assertEqual(len(locust_tests), 2 + 3)
|
|
||||||
name_list = [
|
|
||||||
"create user 1000 and check result.",
|
|
||||||
"create user 1001 and check result."
|
|
||||||
]
|
|
||||||
self.assertIn(locust_tests[0]["config"]["name"], name_list)
|
|
||||||
self.assertIn(locust_tests[4]["config"]["name"], name_list)
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from httprunner.plugins.locusts import prepare_locust_tests
|
||||||
|
|
||||||
|
|
||||||
|
class TestLocust(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_prepare_locust_tests(self):
|
||||||
|
path = os.path.join(
|
||||||
|
os.getcwd(), 'tests/locust_tests/demo_locusts.yml')
|
||||||
|
locust_tests = prepare_locust_tests(path)
|
||||||
|
self.assertEqual(len(locust_tests), 2 + 3)
|
||||||
|
name_list = [
|
||||||
|
"create user 1000 and check result.",
|
||||||
|
"create user 1001 and check result."
|
||||||
|
]
|
||||||
|
self.assertIn(locust_tests[0]["config"]["name"], name_list)
|
||||||
|
self.assertIn(locust_tests[4]["config"]["name"], name_list)
|
||||||
Reference in New Issue
Block a user