Skip to content

Commit eb9c3ab

Browse files
committed
Clean up test_mode.py a bit
1 parent 08ec191 commit eb9c3ab

1 file changed

Lines changed: 7 additions & 47 deletions

File tree

src/software/gameplay_tests/test_mode.py

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ class TestModeSession:
3333
is_yellow_friendly: bool
3434
ci_mode: bool
3535
cancel_event: threading.Event = field(default_factory=threading.Event)
36-
"""Set to ask the in-progress test to stop early so another can run"""
3736

3837

39-
class _ResultCollector:
38+
class ResultCollector:
4039
"""A pytest plugin that records the pass/fail outcome of a run's tests."""
4140

4241
def __init__(self, cancel_event) -> None:
@@ -79,37 +78,9 @@ def summary(self, exit_code) -> str:
7978
return f"{status}: {passed}/{total} passed"
8079

8180

82-
def _reset_session_state(session: TestModeSession) -> None:
83-
"""Halts the AI and clears tactic overrides between runs.
84-
85-
Keeps each run hermetic and, for field tests, stops the robots once a test
86-
finishes.
87-
88-
:param session: the active TestModeSession.
89-
"""
90-
context = session.context
91-
try:
92-
context.gamecontroller.send_gc_command(
93-
gc_command=Command.Type.HALT, team=Team.UNKNOWN
94-
)
95-
empty_tactics = AssignedTacticPlayControlParams()
96-
context.blue_full_system_proto_unix_io.send_proto(
97-
AssignedTacticPlayControlParams, empty_tactics
98-
)
99-
context.yellow_full_system_proto_unix_io.send_proto(
100-
AssignedTacticPlayControlParams, empty_tactics
101-
)
102-
except Exception as exception:
103-
logger.warning(f"Failed to reset state after test: {exception}")
104-
105-
10681
def run_selected_test(session: TestModeSession, test_path: str) -> str:
10782
"""Runs a single gameplay test bound to the given session.
10883
109-
Sets fixture.ACTIVE_SESSION so the gameplay_test_runner fixture binds the
110-
test to the open Thunderscope, runs the test in-process with pytest, then
111-
clears the session and resets state.
112-
11384
:param session: the active TestModeSession.
11485
:param test_path: absolute path to the test file to run.
11586
:return: a human-readable status string describing the outcome.
@@ -118,7 +89,7 @@ def run_selected_test(session: TestModeSession, test_path: str) -> str:
11889
# Clear once per run (not per test in the file) so a cancel set during the
11990
# run stops every remaining test, not just the current one.
12091
session.cancel_event.clear()
121-
collector = _ResultCollector(session.cancel_event)
92+
collector = ResultCollector(session.cancel_event)
12293
try:
12394
# Pass the fixture module as a plugin so gameplay_test_runner is available
12495
# regardless of where pytest resolves conftest.py for the source-tree test.
@@ -135,7 +106,6 @@ def run_selected_test(session: TestModeSession, test_path: str) -> str:
135106
)
136107
finally:
137108
fixture.ACTIVE_SESSION = None
138-
_reset_session_state(session)
139109
return collector.summary(exit_code)
140110

141111

@@ -172,10 +142,6 @@ def _build_test_args(main_args) -> argparse.Namespace:
172142
def launch_test_mode(main_args) -> None:
173143
"""Launches Thunderscope in test mode and runs the Qt event loop.
174144
175-
Starts the gameplay-test binaries once, builds a Thunderscope view with the
176-
Test Runner widget, and keeps everything alive so that tests selected in the
177-
widget run against the already-open Thunderscope.
178-
179145
:param main_args: parsed thunderscope_main command-line arguments.
180146
"""
181147
args = _build_test_args(main_args)
@@ -188,22 +154,16 @@ def launch_test_mode(main_args) -> None:
188154
)
189155

190156
with session_cm as context:
191-
# Must construct the QApplication before any QWidget (the Test Runner
192-
# widget) is created. configure_*_view calls this again, but it is
193-
# idempotent.
157+
# Must construct the QApplication before any QWidget
194158
initialize_application()
195159

196-
# Holds the session so the run callback can reach it; the session is only
197-
# created after the Thunderscope (which needs the widget) exists.
198-
session_holder = {}
160+
session = None
199161

200162
def run_callback(test_path: str) -> str:
201-
return run_selected_test(session_holder["session"], test_path)
163+
return run_selected_test(session, test_path)
202164

203165
def cancel_callback() -> None:
204-
session = session_holder.get("session")
205-
if session is not None:
206-
session.cancel_event.set()
166+
session.cancel_event.set()
207167

208168
test_runner_widget = TScopeWidget(
209169
name="Test Runner",
@@ -225,7 +185,7 @@ def cancel_callback() -> None:
225185
context, main_args.layout, extra_widgets=[test_runner_widget]
226186
)
227187

228-
session_holder["session"] = TestModeSession(
188+
session = TestModeSession(
229189
context=context,
230190
thunderscope=thunderscope,
231191
run_field_test=args.run_field_test,

0 commit comments

Comments
 (0)