{"id":10213,"date":"2022-12-19T10:45:30","date_gmt":"2022-12-19T15:45:30","guid":{"rendered":"https:\/\/www.redline13.com\/blog\/?p=10213"},"modified":"2023-06-22T14:19:36","modified_gmt":"2023-06-22T18:19:36","slug":"load-testing-with-locust-and-jmeter","status":"publish","type":"post","link":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/","title":{"rendered":"Guest Post: Load Testing with Locust and JMeter on RedLine13"},"content":{"rendered":"\n<p>Eldad Uzman, Automation Architect at Merck, is the guest author. You can read more from Eldad at <a data-saferedirecturl=\"https:\/\/www.google.com\/url?q=https:\/\/eldadu1985.medium.com\/&amp;source=gmail&amp;ust=1670336401389000&amp;usg=AOvVaw1sD4mP_30Q8yoO7WMTDtJu\" href=\"https:\/\/eldadu1985.medium.com\/\" target=\"_blank\" rel=\"noopener\">Medium<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Abstract<\/h2>\n\n\n\n<p>In this article, I\u2019ll present to you a case study of how you can integrate Locust into your Redline13 JMeter tests to get the maximum out of your testing environment, increase your load testing coverage while reducing the usage of infrastructure and thus reducing the costs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">JMeter in a nutshell<\/h2>\n\n\n\n<p>JMeter is a java-based load testing tool and one of the most long-standing tools on the market.<\/p>\n\n\n\n<p>For the sake of this article, it\u2019s main characteristic is it\u2019s thread-based architecture, which means that for each virtual user (VU) JMeter will spawn a new thread in the operating system and each thread will perform the tasks related to the test flow of each virtual user.<\/p>\n\n\n\n<p>For the most part, JMeter flows are scripted via its GUI, but it also allows some coding, namely by using groovy language.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Locust in a nutshell<\/h2>\n\n\n\n<p>Locust is a python-based load testing tool, and it is relatively new on the market.<\/p>\n\n\n\n<p>Unlike JMeter, locust is powered by asynchronous io, which means that all virtual users run on a single thread, and concurrency is achieved not by spawning new threads in the operating system but rather by switching between IO contexts using a greenlet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hands on with locust<\/h2>\n\n\n\n<p>Since JMeter is already heavily covered in <a href=\"https:\/\/www.redline13.com\/blog\/docs\/running-a-jmeter-load-test\/\">RedLine13 blog posts<\/a>, in this section I\u2019ll provide a short introduction to the various options available in locust.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p><strong>First<\/strong>, lets make sure we have python installed on our pc:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# python  --version\nPython 3.10.4\nroot@eldaduzman-lap:~#<\/code><\/pre>\n\n\n\n<p><strong>Next<\/strong>, we can install locust using pip<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# pip install locust<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Simple example<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>from itertools import count\nfrom locust import HttpUser, between, task\nUSER_NUMBERS = count(1)\n\nclass WebsiteUser(HttpUser):\n\twait_time = between(10, 12)\n\thost = \"https:\/\/postman-echo.com\"\n\n\tdef __init__(self, *args, **kwargs):\n\t\tself._user_number = next(USER_NUMBERS)\n\t\tsuper().__init__(*args, **kwargs)\n\n\t@task\n\tdef index(self):\n\t\tresponse = self.client.get(f\"\/get?var={self._user_number}\", name=\"get_usr_num\")\n\t\tvar = response.json()&#91;'args']&#91;'var']\n\t\tresponse = self.client.get(f\"\/get?var={var}\", name=\"get_var\")<\/code><\/pre>\n\n\n\n<p>In this example, each virtual user is initiated with a unique sequence number (similar to the __threadNum variable in JMeter) and then it executes its task every 10-12 seconds<\/p>\n\n\n\n<p>The task is to send a one get request with the sequence number, extract the number from the response, and then to send it as a different request.<\/p>\n\n\n\n<p>To execute the locust test script, we can run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# locust -f locustfile.py<\/code><\/pre>\n\n\n\n<p>This will create a web interface that you can open in your browser at `http:\/\/localhost:8089\/\u2019<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"607\" height=\"641\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-5.png\" alt=\"\" class=\"wp-image-10214\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-5.png 607w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-5-284x300.png 284w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-5-425x449.png 425w\" sizes=\"auto, (max-width: 607px) 100vw, 607px\" \/><\/figure>\n\n\n\n<p>We will spawn 20 virtual user and leave them to run for a while<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1883\" height=\"245\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6.png\" alt=\"\" class=\"wp-image-10215\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6.png 1883w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6-300x39.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6-1024x133.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6-768x100.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6-1536x200.png 1536w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-6-425x55.png 425w\" sizes=\"auto, (max-width: 1883px) 100vw, 1883px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1859\" height=\"528\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7.png\" alt=\"\" class=\"wp-image-10216\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7.png 1859w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7-300x85.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7-1024x291.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7-768x218.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7-1536x436.png 1536w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-7-425x121.png 425w\" sizes=\"auto, (max-width: 1859px) 100vw, 1859px\" \/><\/figure>\n\n\n\n<p>Now with the test completed, we see that the average request per second was 3.7, which makes sense, as each user would send 2 requests every ~11 seconds.<\/p>\n\n\n\n<p>Which means that 10.9 requests per minute will be sent from each user.<\/p>\n\n\n\n<p>If we multiply that by 20, the total request per minute count should be 218.18, which would make ~3.63 request per second.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A more complex example<\/h3>\n\n\n\n<p>Let\u2019s try a different scenario, instead of sending http requests, lets send a message to AWS SQS queue<\/p>\n\n\n\n<p>Lets install first boto3 from pip:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# pip install boto3 <\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport time\nimport sys\nimport json\nfrom itertools import count\nfrom locust import User, between, task\n\nimport boto3\nfrom boto3.exceptions import Boto3Error\n\nREGION = os.environ.get(\"REGION\")\nACCESS_KEY = os.environ.get(\"ACCESS_KEY\")\nSECRET_KEY = os.environ.get(\"SECRET_KEY\")\nQUEUE_NAME = os.environ.get(\"QUEUE_NAME\")\n\nassert (\n    REGION and ACCESS_KEY and SECRET_KEY and QUEUE_NAME\n), \"One or more of the following environment variables is missing &#91;REGION | ACCESS_KEY | SECRET_KEY | QUEUE_NAME]\"\n\nUSER_NUMBERS = count(1)\n\ndef get_queue():\n    \"\"\"get boto3 sqs queue object\"\"\"\n    return boto3.resource(\n        \"sqs\",\n        region_name=REGION,\n        aws_access_key_id=ACCESS_KEY,\n        aws_secret_access_key=SECRET_KEY,\n    ).get_queue_by_name(QueueName=QUEUE_NAME)\n\nclass SQSUser(User):\n    wait_time = between(120, 130)\n    host = \"https:\/\/postman-echo.com\"\n\n    def __init__(self, *args, **kwargs):\n        self._user_number = next(USER_NUMBERS)\n        self._queue = get_queue()\n        super().__init__(*args, **kwargs)\n\n    @task\n    def send_sqs_message(self):\n        \"\"\"sends a message to SQS\"\"\"\n        time_start = time.time() * 1000\n\n        try:\n            aws_response = self._queue.send_message(\n                MessageBody=json.dumps({\"user_id\": self._user_number})\n            )\n            time_end = time.time() * 1000\n            self.environment.events.request_success.fire(\n                request_type=\"SQS\",\n                name=\"queue\",\n                response_time=(time_end - time_start),\n                response_length=sys.getsizeof(aws_response),\n            )\n        except Boto3Error as ex:\n            time_end = time.time() * 1000\n            self.environment.events.request_failure.fire(\n                request_type=\"SQS\",\n                name=\"queue\",\n                response_time=(time_end - time_start),\n                exception=ex,\n                response_length=0,\n            )<\/code><\/pre>\n\n\n\n<p>In this example, the script assumes that the details for the SQS queue are stored in the environment variables.<\/p>\n\n\n\n<p>Then it will use the details to generate connections to the sqs, and it will send messages every 120-130 seconds.<\/p>\n\n\n\n<p>Now we can run this script with 50 users<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"640\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-10.png\" alt=\"\" class=\"wp-image-10217\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-10.png 558w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-10-262x300.png 262w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-10-425x487.png 425w\" sizes=\"auto, (max-width: 558px) 100vw, 558px\" \/><\/figure>\n\n\n\n<p>And the results would be as follow:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1888\" height=\"194\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11.png\" alt=\"\" class=\"wp-image-10218\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11.png 1888w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11-300x31.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11-1024x105.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11-768x79.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11-1536x158.png 1536w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-11-425x44.png 425w\" sizes=\"auto, (max-width: 1888px) 100vw, 1888px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1878\" height=\"530\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12.png\" alt=\"\" class=\"wp-image-10219\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12.png 1878w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12-300x85.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12-1024x289.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12-768x217.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12-1536x433.png 1536w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-12-425x120.png 425w\" sizes=\"auto, (max-width: 1878px) 100vw, 1878px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Locust as library<\/h3>\n\n\n\n<p>In the examples above, we would be required to execute locust manually, now let\u2019s run it as a python script<\/p>\n\n\n\n<p>Let\u2019s install another dependency, click, for parsing command line arguments.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# pip install click<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\n\nimport click\nimport gevent\n\nfrom locustfile_sqs import SQSUser\nfrom locust.env import Environment\nfrom locust.html import get_html_report\nfrom locust.env import Environment\nfrom locust.stats import stats_printer, stats_history\n\n@click.option(\n    \"--number-of-users\",\n    help=\"how many locust users to simulate\",\n    type=click.INT,\n    required=True,\n)\n@click.option(\n    \"--duration-in-seconds\",\n    help=\"Duration of execution - if not provided, execution will run infinitely\",\n    type=click.INT,\n    default=-1,\n    required=False,\n)\n@click.option(\n    \"--output-path\",\n    help=\"path to output report\",\n    type=click.STRING,\n    default=\"report.html\",\n    required=False,\n)\ndef main(\n    number_of_users,\n    duration_in_seconds,\n    output_path: str = \"report.html\",\n):\n    env = Environment(user_classes=&#91;SQSUser])\n    env.create_local_runner()\n    assert env.runner, \"must have a runner\"\n    try:\n\n        gevent.spawn(stats_printer(env.stats))\n        gevent.spawn(stats_history, env.runner)\n\n        env.runner.start(number_of_users, spawn_rate=1)\n        if duration_in_seconds &gt; -1:\n            gevent.spawn_later(duration_in_seconds, env.runner.quit)\n        env.runner.greenlet.join()\n    except KeyboardInterrupt:\n        pass\n    finally:\n\n        dir_path = os.path.dirname(os.path.abspath(output_path))\n        if not os.path.exists(dir_path):\n            os.makedirs(dir_path)\n        with open(output_path, \"w\", encoding=\"utf-8\") as html_file:\n            html_file.write(get_html_report(environment=env))\n\ndispatch = click.command()(main)  # make pylint happy\nif __name__ == \"__main__\":\n    dispatch()<\/code><\/pre>\n\n\n\n<p>In this script, we use click to collect 3 command line argument:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>number-of-users<\/li>\n\n\n\n<li>duration-in-seconds<\/li>\n\n\n\n<li>output-path<\/li>\n<\/ul>\n\n\n\n<p>Then we take the SQSUser class we\u2019ve created earlier and run it programmatically without the GUI.<\/p>\n\n\n\n<p>At the end of the script, it will save the html report in the given path<\/p>\n\n\n\n<p>To run this code, the command line can look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# python main.py --number-of-users 50--duration-in-seconds 300 <\/code><\/pre>\n\n\n\n<p>So we spawned up 50 SQS users for 300 seconds.<\/p>\n\n\n\n<p>The results is:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1506\" height=\"508\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16.png\" alt=\"\" class=\"wp-image-10220\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16.png 1506w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16-300x101.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16-1024x345.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16-768x259.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-16-425x143.png 425w\" sizes=\"auto, (max-width: 1506px) 100vw, 1506px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Locust as executable<\/h3>\n\n\n\n<p>So far, we\u2019ve created a python script that runs locust programmatically.<br>However, to use the script, we need the target machine to have python installed and it must have all the prerequisites packages installed as well.<\/p>\n\n\n\n<p>This might be a bit difficult to manage.<br>Ideally, we would like to have a self-contained executable which can be simply executed directly, and luckily this is possible by using <strong>pyinstaller<\/strong>!<\/p>\n\n\n\n<p>Pyinstaller creates a self-contained file that wraps your python code with the python interpreter, libraries and other resources for you to execute in other machines of equal configuration.<\/p>\n\n\n\n<p>This is made possible thanks to the new <a href=\"https:\/\/www.redline13.com\/blog\/docs\/release-notes\/\">RedLine13 version<\/a> which runs ubuntu version 22.04.<\/p>\n\n\n\n<p>So lets first install pyinstaller using pip<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# pip install pyinstaller <\/code><\/pre>\n\n\n\n<p>Now, we can wrap the main file as an executable with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~# pyinstaller --onefile main.py --add-data\nvenv\/lib\/python3.10\/site-packages\/locust\/static:locust\/static --add-data\nvenv\/lib\/python3.10\/site-packages\/locust\/templates\/:locust\/templates<\/code><\/pre>\n\n\n\n<p>This creates the self-contained file with locust static files and templates.<\/p>\n\n\n\n<p>The file is in the `dist` directory under the name `main`.<\/p>\n\n\n\n<p>Now we can run this file directly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>root@eldaduzman-lap:~#.\/main --number-of-users 50 --duration-in-seconds 300 <\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Connecting all the dots<\/h2>\n\n\n\n<p>We\u2019ve created a self-contined executable file, now we can take this file and run it from with in the context of JMeter \ud83d\ude0a<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1283\" height=\"739\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20.png\" alt=\"\" class=\"wp-image-10221\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20.png 1283w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20-300x173.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20-1024x590.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20-768x442.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-20-425x245.png 425w\" sizes=\"auto, (max-width: 1283px) 100vw, 1283px\" \/><\/figure>\n\n\n\n<p>Let\u2019s take a look at the groovy code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import org.apache.commons.io.IOUtils;\ndef do_command(command_args, uname=null){\n    log.info(command_args);\n    def proc = new ProcessBuilder( command_args.split(' ')\n).redirectErrorStream(true);\n    if (uname != null){\n        proc.redirectOutput(new File('.\/output\/'+uname));\n        proc.redirectErrorStream(true);\n    }\n    Process process = proc.start();\n    return process;\n}<\/code>\n<code>SampleResult.setIgnore()<\/code>\n<code>def how_many_users = (vars.get(\"how_many_users\").toInteger()*10).toString()\ndef duration_seconds = vars.get(\"how_many_seconds\")<\/code>\n<code>def exec_command = String.format(\".\/main --number-of-users %s --duration-in-seconds\n%s\", how_many_users, duration_seconds);<\/code>\n<code>log.info(exec_command)\nlog.info(\"chmod +x main \".execute().text)<\/code>\n<code>do_command(exec_command ,'process.log')<\/code><\/code><\/pre>\n\n\n\n<p>In this script, we execute `main` with the inputs from the user defined variables:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"307\" height=\"71\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-22.png\" alt=\"\" class=\"wp-image-10222\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-22.png 307w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-22-300x69.png 300w\" sizes=\"auto, (max-width: 307px) 100vw, 307px\" \/><\/figure>\n\n\n\n<p>For each JMeter user, locust will run 10 users and then the report will be restored in RedLine13\u2019s output directory.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Load Testing with Locust and JMeter on RedLine13<\/h2>\n\n\n\n<p>Now lets run this from RedLine13:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1505\" height=\"606\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23.png\" alt=\"Load Testing with Locust and JMeter on RedLine13\" class=\"wp-image-10223\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23.png 1505w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23-300x121.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23-1024x412.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23-768x309.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-23-425x171.png 425w\" sizes=\"auto, (max-width: 1505px) 100vw, 1505px\" \/><\/figure>\n\n\n\n<p>After the test is completed, lets look at the results:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1461\" height=\"547\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24.png\" alt=\"Load Testing with Locust and JMeter on RedLine13\" class=\"wp-image-10224\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24.png 1461w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24-300x112.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24-1024x383.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24-768x288.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-24-425x159.png 425w\" sizes=\"auto, (max-width: 1461px) 100vw, 1461px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1456\" height=\"483\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25.png\" alt=\"\" class=\"wp-image-10225\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25.png 1456w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25-300x100.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25-1024x340.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25-768x255.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-25-425x141.png 425w\" sizes=\"auto, (max-width: 1456px) 100vw, 1456px\" \/><\/figure>\n\n\n\n<p>And we can also go into the output file and see the locust html report:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1527\" height=\"520\" src=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26.png\" alt=\"\" class=\"wp-image-10226\" srcset=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26.png 1527w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26-300x102.png 300w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26-1024x349.png 1024w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26-768x262.png 768w, https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/word-image-10213-26-425x145.png 425w\" sizes=\"auto, (max-width: 1527px) 100vw, 1527px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Why?<\/h2>\n\n\n\n<p>So, after the demo is completed, now we can go back to the question \u2013 why on earth would we go through all this trouble?<\/p>\n\n\n\n<p>The different architectural style, thread-based vs asyncio-based, make these two tools excel in different domains.<br>For the most part, it seems that locust is better at large number of virtual users with low traffic, and JMeter is better at generating high traffic from a smaller number of users.<\/p>\n\n\n\n<p>There could be some exceptions to the rule, but if you find yourself in a situation where you need to combine the two, it might be helpful for you to use this solution and reduce the costs of your load testing efforts.<\/p>\n\n\n\n<p>Likewise, some test flows are easier to implement in locust, owing to the massively rich python eco-system.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">On a final note<\/h2>\n\n\n\n<p>This case study illustrates RedLine13\u2019s remarkable flexibility.<\/p>\n\n\n\n<p>In a sense, RedLine13 provides not only with a test execution environment but you also get an experiment environment to explore different possibilities.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">External links<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/locust.io\/\">locust<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/pyinstaller.org\/en\/stable\/\">pyinstaller<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/click.palletsprojects.com\/en\/8.1.x\/\">click<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Try RedLine13<\/h2>\n\n\n\n<p>You can&nbsp;<a href=\"https:\/\/www.redline13.com\/Service\">sign up<\/a> and try RedLine13 today for any load testing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eldad Uzman, Automation Architect at Merck, is the guest author. You can read more from Eldad at Medium. Abstract In this article, I\u2019ll present to you a case study of how you can integrate Locust into your Redline13 JMeter tests to get the maximum out of your testing environment, increase your load testing coverage while reducing the usage of infrastructure and thus reducing the costs. JMeter in a nutshell JMeter is a java-based load testing tool<a class=\"more-link\" href=\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\">Read More &rarr;<\/a><\/p>\n","protected":false},"author":12,"featured_media":10293,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,586,7],"tags":[283,318,330],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-eldad","4":"post-10213","6":"format-standard","7":"has-post-thumbnail","8":"category-blog","9":"category-customer","10":"category-jmeter","11":"post_tag-jmeter","12":"post_tag-load-testing","13":"post_tag-locust-io"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.12 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Guest Post: Load Testing with Locust and JMeter on RedLine13<\/title>\n<meta name=\"description\" content=\"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Guest Post: Load Testing with Locust and JMeter on RedLine13\" \/>\n<meta property=\"og:description\" content=\"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\" \/>\n<meta property=\"og:site_name\" content=\"RedLine13\" \/>\n<meta property=\"article:published_time\" content=\"2022-12-19T15:45:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-22T18:19:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/Locust.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"310\" \/>\n\t<meta property=\"og:image:height\" content=\"163\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eldad Uzman\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eldad Uzman\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\"},\"author\":{\"name\":\"Eldad Uzman\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/ffd0bd4dde7217c3e16f1ae03286a08a\"},\"headline\":\"Guest Post: Load Testing with Locust and JMeter on RedLine13\",\"datePublished\":\"2022-12-19T15:45:30+00:00\",\"dateModified\":\"2023-06-22T18:19:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\"},\"wordCount\":1081,\"publisher\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#organization\"},\"keywords\":[\"JMeter\",\"Load Testing\",\"locust.io\"],\"articleSection\":[\"Blog\",\"Customer\",\"JMeter\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\",\"url\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\",\"name\":\"Guest Post: Load Testing with Locust and JMeter on RedLine13\",\"isPartOf\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#website\"},\"datePublished\":\"2022-12-19T15:45:30+00:00\",\"dateModified\":\"2023-06-22T18:19:36+00:00\",\"description\":\"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.redline13.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Guest Post: Load Testing with Locust and JMeter on RedLine13\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#website\",\"url\":\"https:\/\/www.redline13.com\/blog\/\",\"name\":\"RedLine13\",\"description\":\"(Almost) Free Load Testing in the Cloud\",\"publisher\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.redline13.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#organization\",\"name\":\"RedLine13\",\"url\":\"https:\/\/www.redline13.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg\",\"contentUrl\":\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg\",\"width\":300,\"height\":68,\"caption\":\"RedLine13\"},\"image\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/ffd0bd4dde7217c3e16f1ae03286a08a\",\"name\":\"Eldad Uzman\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/07ca72c4076c07cbd0e83be9e1245d7e64a1f1005966352b9b2bd35e973b0d08?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/07ca72c4076c07cbd0e83be9e1245d7e64a1f1005966352b9b2bd35e973b0d08?s=96&d=mm&r=g\",\"caption\":\"Eldad Uzman\"},\"url\":\"https:\/\/www.redline13.com\/blog\/author\/eldad\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Guest Post: Load Testing with Locust and JMeter on RedLine13","description":"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/","og_locale":"en_US","og_type":"article","og_title":"Guest Post: Load Testing with Locust and JMeter on RedLine13","og_description":"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.","og_url":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/","og_site_name":"RedLine13","article_published_time":"2022-12-19T15:45:30+00:00","article_modified_time":"2023-06-22T18:19:36+00:00","og_image":[{"width":310,"height":163,"url":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2022\/12\/Locust.jpeg","type":"image\/jpeg"}],"author":"Eldad Uzman","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Eldad Uzman","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#article","isPartOf":{"@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/"},"author":{"name":"Eldad Uzman","@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/ffd0bd4dde7217c3e16f1ae03286a08a"},"headline":"Guest Post: Load Testing with Locust and JMeter on RedLine13","datePublished":"2022-12-19T15:45:30+00:00","dateModified":"2023-06-22T18:19:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/"},"wordCount":1081,"publisher":{"@id":"https:\/\/www.redline13.com\/blog\/#organization"},"keywords":["JMeter","Load Testing","locust.io"],"articleSection":["Blog","Customer","JMeter"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/","url":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/","name":"Guest Post: Load Testing with Locust and JMeter on RedLine13","isPartOf":{"@id":"https:\/\/www.redline13.com\/blog\/#website"},"datePublished":"2022-12-19T15:45:30+00:00","dateModified":"2023-06-22T18:19:36+00:00","description":"Learn how Merck integrates Locust into Redline13 JMeter tests to get the maximum out of their testing environment while reducing the costs.","breadcrumb":{"@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.redline13.com\/blog\/2022\/12\/load-testing-with-locust-and-jmeter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.redline13.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Guest Post: Load Testing with Locust and JMeter on RedLine13"}]},{"@type":"WebSite","@id":"https:\/\/www.redline13.com\/blog\/#website","url":"https:\/\/www.redline13.com\/blog\/","name":"RedLine13","description":"(Almost) Free Load Testing in the Cloud","publisher":{"@id":"https:\/\/www.redline13.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.redline13.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.redline13.com\/blog\/#organization","name":"RedLine13","url":"https:\/\/www.redline13.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg","contentUrl":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg","width":300,"height":68,"caption":"RedLine13"},"image":{"@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/ffd0bd4dde7217c3e16f1ae03286a08a","name":"Eldad Uzman","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/07ca72c4076c07cbd0e83be9e1245d7e64a1f1005966352b9b2bd35e973b0d08?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/07ca72c4076c07cbd0e83be9e1245d7e64a1f1005966352b9b2bd35e973b0d08?s=96&d=mm&r=g","caption":"Eldad Uzman"},"url":"https:\/\/www.redline13.com\/blog\/author\/eldad\/"}]}},"_links":{"self":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/posts\/10213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/comments?post=10213"}],"version-history":[{"count":10,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/posts\/10213\/revisions"}],"predecessor-version":[{"id":10428,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/posts\/10213\/revisions\/10428"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/media\/10293"}],"wp:attachment":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/media?parent=10213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/categories?post=10213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/tags?post=10213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}