{"id":13650914,"url":"https://github.com/eldaduzman/pymeter","last_synced_at":"2025-04-14T06:43:54.458Z","repository":{"id":60705936,"uuid":"540299832","full_name":"eldaduzman/pymeter","owner":"eldaduzman","description":"Simple JMeter performance tests API for python","archived":false,"fork":false,"pushed_at":"2023-12-05T13:18:43.000Z","size":995,"stargazers_count":52,"open_issues_count":4,"forks_count":10,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-29T00:25:59.161Z","etag":null,"topics":["automation","java","jmeter","load-testing","performance-testing","python","qa-automation"],"latest_commit_sha":null,"homepage":"https://pymeter.readthedocs.io/en/latest/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eldaduzman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-09-23T05:57:33.000Z","updated_at":"2024-04-28T15:21:38.000Z","dependencies_parsed_at":"2024-01-03T05:48:38.128Z","dependency_job_id":null,"html_url":"https://github.com/eldaduzman/pymeter","commit_stats":{"total_commits":151,"total_committers":5,"mean_commits":30.2,"dds":0.08609271523178808,"last_synced_commit":"4e36e7efc12fa5ced31d1597328ba5c22a78f66a"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Fpymeter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Fpymeter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Fpymeter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eldaduzman%2Fpymeter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eldaduzman","download_url":"https://codeload.github.com/eldaduzman/pymeter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248837265,"owners_count":21169373,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","java","jmeter","load-testing","performance-testing","python","qa-automation"],"created_at":"2024-08-02T02:00:42.480Z","updated_at":"2025-04-14T06:43:54.430Z","avatar_url":"https://github.com/eldaduzman.png","language":"Python","funding_links":[],"categories":["Automation"],"sub_categories":["DSL"],"readme":"# pymeter\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\nSimple JMeter performance tests API for python\n\n#### Powered by [JMeter-DSL](https://abstracta.github.io/jmeter-java-dsl/) and [pyjnius](https://github.com/kivy/pyjnius) \n\n\n[![Version](https://img.shields.io/pypi/v/pymeter.svg)](https://pypi.python.org/pypi/pymeter)\n![](https://raw.githubusercontent.com/eldaduzman/pymeter/main/docs/badges/coverage-badge.svg)\n![](https://raw.githubusercontent.com/eldaduzman/pymeter/main/docs/badges/pylint.svg)\n![](https://raw.githubusercontent.com/eldaduzman/pymeter/main/docs/badges/mutscore.svg)\n[![Generic badge](https://img.shields.io/badge/python-3.8|3.9|3.10|3.11-blue.svg)](https://python.org/)\n[![Generic badge](https://img.shields.io/badge/JMeterDsl-1.23.3-blue.svg)](https://abstracta.github.io/jmeter-java-dsl/)\n[![Documentation Status](https://readthedocs.org/projects/pymeter/badge/?version=latest)](https://pymeter.readthedocs.io/en/latest/?badge=latest)\n\n\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n\n\u003cbr/\u003e\n\n\u003cdiv style=\"text-align:center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/eldaduzman/pymeter/main/docs/user-guide/source/_static/pymeter-logo-full.jpg\" width=\"70%\" /\u003e\u003c/div\u003e\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n\n\n## Load testing with JMeter using python!\n\n\nRead the documentation [here](https://pymeter.readthedocs.io/en/latest/) \u003cbr/\u003e\nRead about performance benchmarking [here](https://github.com/eldaduzman/pymeter-benchmark)\n\n**JMeter** is one of the most popular and long standing load testing tools. \u003cbr/\u003e\nThe original implementation is a gui based tool to script load test scenarios in a hierarchical structure, however this came with limitations and shortcomings.\n\nFor once, upgrading JMeter versions is painful, as it involved manually downloading and deploying executable files.\nThis became very clear when [log4j](https://en.wikipedia.org/wiki/Log4Shell) vulnerability was discovered, and software developers needed to instantly upgrade their log4j versions.\nWith JMeter, this was even more painful without a proper package management system such as maven or gradle.\n\nOther limitations include difficulty to share code between different projects, using source control management tools such as git or svn.\nIt is quite difficult to extend JMeter and it requires a GUI editor which means to use additional development environment instead of using a single IDE for all needs.\n\nThe awesome folks at [abstracta](https://abstracta.us/) have put up an amazing amount of work to deliver [JMeter-DSL](https://abstracta.github.io/jmeter-java-dsl/), which allows developers to use plain Java to script their load test scenarios, and pretty much solve all the pain mentioned above.\n\n`pymeter` project is aimed to capitalize on the success of JMeter-DSL and extend it to the python community!\nUsing [pyjnius](https://github.com/kivy/pyjnius) developed by Kivy, it is possible to bridge between JMeter-DSLs classes written in Java and reflect them into python's runtime environment without spawning up java runtime and relying on costly inter-process communication.\n\n\n### Pre-requisites:\n1. python version 3.9 or higher - [download](https://www.python.org/)\n2. Java version 8 or 11 - [download](https://adoptium.net/temurin/releases)\n3. JAVA_HOME environment variable set - [read](https://confluence.atlassian.com/doc/setting-the-java_home-variable-in-windows-8895.html)\n\n### Install pymeter\n```bash\n\u003e\u003e\u003e pip install pymeter\n```\n\n### simple pymeter script:\n\n```python\n\"\"\"unittest module\"\"\"\nfrom unittest import TestCase, main\n\nfrom pymeter.api.config import TestPlan, ThreadGroupWithRampUpAndHold\nfrom pymeter.api.postprocessors import JsonExtractor\nfrom pymeter.api.reporters import HtmlReporter\nfrom pymeter.api.samplers import DummySampler, HttpSampler\nfrom pymeter.api.timers import UniformRandomTimer\n\n\nclass TestTestPlanClass(TestCase):\n    def test_1(self):\n        json_extractor = JsonExtractor(\"variable\", \"args.var\")\n        timer = UniformRandomTimer(1000, 2000)\n        http_sampler = HttpSampler(\n            \"Echo\",\n            \"https://postman-echo.com/get?var=${__Random(0,10)}\",\n            timer,\n            json_extractor,\n        )\n        dummy_sampler = DummySampler(\"dummy ${variable}\", \"hi dummy\")\n        tg = ThreadGroupWithRampUpAndHold(\n            10, 1, 60, http_sampler, dummy_sampler, name=\"Some Name\"\n        )\n        html_reporter = HtmlReporter()\n        tp = TestPlan(tg, html_reporter)\n        stats = tp.run()\n        print(\n            f\"duration= {stats.duration_milliseconds}\",\n            f\"mean= {stats.sample_time_mean_milliseconds}\",\n            f\"min= {stats.sample_time_min_milliseconds}\",\n            f\"median= {stats.sample_time_median_milliseconds}\",\n            f\"90p= {stats.sample_time_90_percentile_milliseconds}\",\n            f\"95p= {stats.sample_time_95_percentile_milliseconds}\",\n            f\"99p= {stats.sample_time_99_percentile_milliseconds}\",\n            f\"max= {stats.sample_time_max_milliseconds}\",\n            sep=\"\\t\",\n        )\n        self.assertLess(stats.sample_time_99_percentile_milliseconds, 2000)\n\n\nif __name__ == \"__main__\":\n    main()\n\n```\n\nIn this example, the standard python unittest was used to execute the test code, however pymeter is framework agnostic and can be used by any other testing framework\n\n## File Structure\n\n```\n|   .coverage\n|   .gitignore\n|   .pylintrc\n|   cosmic-ray-config.ini\n|   LICENSE\n|   make.bat\n|   Makefile\n|   poetry.lock\n|   pyproject.toml\n|   README.md\n|   tox.ini               \n+---source\n|   |   conf.py\n|   |   index.rst\n|   |   \n|   +---_static\n|   \\---_templates\n+---src\n|   \\---pymeter\n|       |   __init__.py\n|       |   \n|       +---api\n|       |   |   config.py\n|       |   |   postprocessors.py\n|       |   |   reporters.py\n|       |   |   samplers.py\n|       |   |   timers.py\n|       |   |   __init__.py\n|       |   |   \n+---utests\n|   |   test_postprocessors.py\n|   |   test_reporter.py\n|   |   test_sampler.py\n|   |   test_test_plan.py\n|   |   test_thread_group.py\n|   |   test_timers.py\n|   |   __init__.py\n|   |   \n```\n## Code styling\n### `black` used for auto-formatting code [read](https://pypi.org/project/black/),\n### `pylint` used for code linting and pep8 compliance [read](https://pypi.org/project/pylint/),\n### `mypy` used for type hinting [read](https://pypi.org/project/mypy/),\n### `perflint` pylint extension for performance linting [read](https://betterprogramming.pub/use-perflint-a-performance-linter-for-python-eae8e54f1e99)\n### `cosmic-ray` Python tool for mutation testing [read](https://python.plainenglish.io/python-mutation-testing-with-cosmic-ray-4b78eb9e0676)\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.linkedin.com/in/antonio-zaitoun/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/17438617?v=4?s=100\" width=\"100px;\" alt=\"Antonio Zaitoun\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAntonio Zaitoun\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/eldaduzman/pymeter/commits?author=Minitour\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\"\u003e\u003ca href=\"https://medium.com/@eldadu1985\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/55621402?v=4?s=100\" width=\"100px;\" alt=\"Eldad Uzman\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEldad Uzman\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-eldaduzman\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/eldaduzman/pymeter/commits?author=eldaduzman\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/eldaduzman/pymeter/commits?author=eldaduzman\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n## links\n1. [JMeter Dsl](https://abstracta.github.io/jmeter-java-dsl/)\n2. [pyjnius](https://github.com/kivy/pyjnius)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldaduzman%2Fpymeter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feldaduzman%2Fpymeter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feldaduzman%2Fpymeter/lists"}