From 08ebdc342ee74ee7840d261adc6cbe9ce87e9fe5 Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Wed, 15 May 2024 13:00:08 +0200 Subject: [PATCH 1/2] Give better error message if User subclass doesnt call base constructor. --- locust/runners.py | 3 +++ locust/test/test_runners.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/locust/runners.py b/locust/runners.py index 4c3c8451da..6cef63762a 100644 --- a/locust/runners.py +++ b/locust/runners.py @@ -223,6 +223,9 @@ def spawn(user_class: str, spawn_count: int) -> list[User]: new_users: list[User] = [] while n < spawn_count: new_user = self.user_classes_by_name[user_class](self.environment) + assert hasattr( + new_user, "environment" + ), f"Attribute 'environment' is missing on user {user_class}. Perhaps you defined your own __init__ and forgot to call the base constructor? (super().__init__(*args, **kwargs))" new_user.start(self.user_greenlets) new_users.append(new_user) n += 1 diff --git a/locust/test/test_runners.py b/locust/test/test_runners.py index 0397e02550..3ef8c12124 100644 --- a/locust/test/test_runners.py +++ b/locust/test/test_runners.py @@ -144,6 +144,24 @@ def reset_state(self): class TestLocustRunner(LocustRunnerTestCase): + def test_missing_constructor_call_in_user(self): + class BadUser(User): + def __init__(self, *args, **kwargs): + pass # not calling base class constructor!!! + + @task + def t(self): + pass + + environment = Environment(user_classes=[BadUser]) + runner = LocalRunner(environment) + with self.assertRaises(AssertionError) as assert_raises_context: + runner.spawn_users({BadUser.__name__: 1}) + self.assertIn( + "Perhaps you defined your own __init__ and forgot to call the base constructor", + str(assert_raises_context.exception), + ) + def test_cpu_warning(self): _monitor_interval = runners.CPU_MONITOR_INTERVAL runners.CPU_MONITOR_INTERVAL = 2.0 From 2ab11c36eada9f178a54102e658922433b1304a9 Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Wed, 15 May 2024 13:51:22 +0200 Subject: [PATCH 2/2] test_runners: More detailed test. --- locust/test/test_runners.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locust/test/test_runners.py b/locust/test/test_runners.py index 3ef8c12124..4c6b8a37e7 100644 --- a/locust/test/test_runners.py +++ b/locust/test/test_runners.py @@ -158,7 +158,7 @@ def t(self): with self.assertRaises(AssertionError) as assert_raises_context: runner.spawn_users({BadUser.__name__: 1}) self.assertIn( - "Perhaps you defined your own __init__ and forgot to call the base constructor", + "Attribute 'environment' is missing on user BadUser. Perhaps you defined your own __init__ and forgot to call the base constructor", str(assert_raises_context.exception), )