From f21b8c354a5422ded6863af908ca5d25c9c6866f Mon Sep 17 00:00:00 2001 From: Eldad Uzman Date: Sun, 6 Nov 2022 16:23:45 +0200 Subject: [PATCH 1/3] add vars class --- src/pymeter/api/config.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/pymeter/api/config.py b/src/pymeter/api/config.py index 613574b..778ef0c 100644 --- a/src/pymeter/api/config.py +++ b/src/pymeter/api/config.py @@ -131,6 +131,7 @@ def tearDownClass(cls): ------------- """ import os +from typing import Optional from jnius import JavaException from pymeter.api import ( @@ -144,6 +145,28 @@ class BaseConfigElement(TestPlanChildElement): """base class for all config elements""" +class Vars(TestPlanChildElement): + """Vars are key value pairs""" + + def __init__(self, values: Optional[dict[str, str]] = None) -> None: + self._vars_instance = TestPlanChildElement.jmeter_class.vars() + if values: + for key, value in values.items(): + self.set(key, value) + super().__init__() + + def children(self, *children): + raise ChildrenAreNotAllowed("Cant append children to vars") + + def set(self, key: str, value: str): + """Sets a single key value pair""" + if not isinstance(key, str): + raise TypeError("Keys must be strings") + + self._vars_instance.set(key, str(value)) + return self + + class CsvDataset(TestPlanChildElement, ThreadGroupChildElement): """ csv data set allows you to append unique data set to samplers From f20b98e1f937c2d0f5f9a8f34038ff7696576be1 Mon Sep 17 00:00:00 2001 From: Eldad Uzman Date: Sun, 6 Nov 2022 16:49:03 +0200 Subject: [PATCH 2/3] update documentation --- src/pymeter/api/config.py | 42 ++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/pymeter/api/config.py b/src/pymeter/api/config.py index 778ef0c..8a0b9c5 100644 --- a/src/pymeter/api/config.py +++ b/src/pymeter/api/config.py @@ -104,8 +104,42 @@ def tearDownClass(cls): example - 4: -------------- +We can create vars from with in JMeters context using the `Vars` class + + .. code-block:: python + from pymeter.api.config import TestPlan, ThreadGroupSimple, Vars + from pymeter.api.samplers import HttpSampler + from pymeter.api.timers import ConstantTimer + from pymeter.api.reporters import HtmlReporter + + jmeter_variables = Vars(id1="value1", id2="value2") + html_reporter = HtmlReporter() + timer = ConstantTimer(2000) + http_sampler1 = HttpSampler( + "Echo_${id1}", "https://postman-echo.com/get?var=${id1}", timer + ) + thread_group1 = ThreadGroupSimple(3, 1) + thread_group1.children(http_sampler1) + + + http_sampler2 = HttpSampler("Echo_${id2}", "https://postman-echo.com/get?var=do", timer) + thread_group2 = ThreadGroupSimple(3, 1, http_sampler2) + test_plan = TestPlan(thread_group1, thread_group2, html_reporter, jmeter_variables) + stats = test_plan.run() + +We can also set a single variable using the `set` method + .. code-block:: python + from pymeter.api.config import Vars + jmeter_variables = Vars(id1="value1", id2="value2") + jmeter_variables.set("id1", "v2") + +example - 5: +-------------- + We Can also generate data for each thread group: + .. code-block:: python + from pymeter.api.config import TestPlan, ThreadGroupSimple, CsvDataset from pymeter.api.samplers import HttpSampler from pymeter.api.timers import ConstantTimer @@ -131,7 +165,6 @@ def tearDownClass(cls): ------------- """ import os -from typing import Optional from jnius import JavaException from pymeter.api import ( @@ -148,11 +181,10 @@ class BaseConfigElement(TestPlanChildElement): class Vars(TestPlanChildElement): """Vars are key value pairs""" - def __init__(self, values: Optional[dict[str, str]] = None) -> None: + def __init__(self, **vars) -> None: self._vars_instance = TestPlanChildElement.jmeter_class.vars() - if values: - for key, value in values.items(): - self.set(key, value) + for key, value in vars.items(): + self.set(key, value) super().__init__() def children(self, *children): From fe2c72d749afff9b082e437668162c3717e6fe78 Mon Sep 17 00:00:00 2001 From: Eldad Uzman Date: Sun, 6 Nov 2022 17:18:45 +0200 Subject: [PATCH 3/3] add unit tests --- src/pymeter/api/config.py | 4 +- utests/test_csv_data_set.py | 2 +- utests/test_vars.py | 131 ++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 utests/test_vars.py diff --git a/src/pymeter/api/config.py b/src/pymeter/api/config.py index 8a0b9c5..e1622e6 100644 --- a/src/pymeter/api/config.py +++ b/src/pymeter/api/config.py @@ -181,9 +181,9 @@ class BaseConfigElement(TestPlanChildElement): class Vars(TestPlanChildElement): """Vars are key value pairs""" - def __init__(self, **vars) -> None: + def __init__(self, **variables) -> None: self._vars_instance = TestPlanChildElement.jmeter_class.vars() - for key, value in vars.items(): + for key, value in variables.items(): self.set(key, value) super().__init__() diff --git a/utests/test_csv_data_set.py b/utests/test_csv_data_set.py index 4f75ff0..556a7d3 100644 --- a/utests/test_csv_data_set.py +++ b/utests/test_csv_data_set.py @@ -20,7 +20,7 @@ class TestCsvDataSet(TestCase): def test_csv_data_set_children(self): with self.assertRaises(ChildrenAreNotAllowed) as exp: - CsvDataset("utests/test_csv_data_set.py").children() + CsvDataset(CSV_FILE_PATH).children() self.assertEqual( str(exp.exception), "Cant append children to a csv_data_set", diff --git a/utests/test_vars.py b/utests/test_vars.py new file mode 100644 index 0000000..2cad5aa --- /dev/null +++ b/utests/test_vars.py @@ -0,0 +1,131 @@ +"""unittest module""" +import os +import uuid +from unittest import TestCase, main +from collections import Counter +from pymeter.api import ChildrenAreNotAllowed +from pymeter.api.config import ( + TestPlan, + ThreadGroupSimple, + Vars, +) +from pymeter.api.reporters import HtmlReporter +from pymeter.api.samplers import HttpSampler + + +class TestVars(TestCase): + """Testing vars""" + + def test_vars_children(self): + with self.assertRaises(ChildrenAreNotAllowed) as exp: + Vars().children() + self.assertEqual( + str(exp.exception), + "Cant append children to vars", + ) + + def test_vars_set_from_constructor(self): + + output_dir = os.path.join("output", str(uuid.uuid4())) + html_reporter = HtmlReporter(output_dir) + variables = Vars(my_id="value1") + http_sampler1 = HttpSampler( + "Echo_${my_id}", "https://postman-echo.com/get?var=${my_id}" + ) + thread_group = ThreadGroupSimple(2, 1) + thread_group.children(http_sampler1) + + test_plan = TestPlan(thread_group, html_reporter, variables) + test_plan.run() + + self.assertTrue(os.path.exists(output_dir)) + path_to_jtl = os.path.join(output_dir, "report.jtl") + with open(path_to_jtl, "r", encoding="utf-8") as jtl_file: + next(jtl_file) + all_samplers = [line.split(",")[2] for line in jtl_file] + cntr = Counter(all_samplers) + self.assertDictEqual({"Echo_value1": 2}, cntr) + + def test_vars_set_from_set_method(self): + + output_dir = os.path.join("output", str(uuid.uuid4())) + html_reporter = HtmlReporter(output_dir) + variables = Vars() + variables.set("my_id", "value1") + http_sampler1 = HttpSampler( + "Echo_${my_id}", "https://postman-echo.com/get?var=${my_id}" + ) + thread_group = ThreadGroupSimple(2, 1) + thread_group.children(http_sampler1) + + test_plan = TestPlan(thread_group, html_reporter, variables) + test_plan.run() + + self.assertTrue(os.path.exists(output_dir)) + path_to_jtl = os.path.join(output_dir, "report.jtl") + with open(path_to_jtl, "r", encoding="utf-8") as jtl_file: + next(jtl_file) + all_samplers = [line.split(",")[2] for line in jtl_file] + cntr = Counter(all_samplers) + self.assertDictEqual({"Echo_value1": 2}, cntr) + + def test_vars_value_is_int(self): + + output_dir = os.path.join("output", str(uuid.uuid4())) + html_reporter = HtmlReporter(output_dir) + variables = Vars() + variables.set("my_id", 1) + http_sampler1 = HttpSampler( + "Echo_${my_id}", "https://postman-echo.com/get?var=${my_id}" + ) + thread_group = ThreadGroupSimple(2, 1) + thread_group.children(http_sampler1) + + test_plan = TestPlan(thread_group, html_reporter, variables) + test_plan.run() + + self.assertTrue(os.path.exists(output_dir)) + path_to_jtl = os.path.join(output_dir, "report.jtl") + with open(path_to_jtl, "r", encoding="utf-8") as jtl_file: + next(jtl_file) + all_samplers = [line.split(",")[2] for line in jtl_file] + cntr = Counter(all_samplers) + self.assertDictEqual({"Echo_1": 2}, cntr) + + def test_vars_value_is_stringable_class(self): + class C: + def __repr__(self) -> str: + return "hello" + + output_dir = os.path.join("output", str(uuid.uuid4())) + html_reporter = HtmlReporter(output_dir) + variables = Vars() + variables.set("my_id", C()) + http_sampler1 = HttpSampler( + "Echo_${my_id}", "https://postman-echo.com/get?var=${my_id}" + ) + thread_group = ThreadGroupSimple(2, 1) + thread_group.children(http_sampler1) + + test_plan = TestPlan(thread_group, html_reporter, variables) + test_plan.run() + + self.assertTrue(os.path.exists(output_dir)) + path_to_jtl = os.path.join(output_dir, "report.jtl") + with open(path_to_jtl, "r", encoding="utf-8") as jtl_file: + next(jtl_file) + all_samplers = [line.split(",")[2] for line in jtl_file] + cntr = Counter(all_samplers) + self.assertDictEqual({"Echo_hello": 2}, cntr) + + def test_vars_illegal_key_type(self): + + with self.assertRaises(TypeError) as exp: + variables = Vars() + variables.set(1, "value1") + + self.assertEqual(str(exp.exception), "Keys must be strings") + + +if __name__ == "__main__": + main()