test_multi_breakpoint_scenarios.py•11.8 kB
"""Multi-breakpoint scenario tests.
Tests cover complex debugging workflows with multiple breakpoints.
"""
from pathlib import Path
import sys
import pytest
from mcp_debug_tool.schemas import BreakpointRequest, StartSessionRequest
from mcp_debug_tool.sessions import SessionManager
@pytest.fixture
def workspace_root(tmp_path: Path) -> Path:
"""Create a temporary workspace for testing."""
return tmp_path
@pytest.fixture
def manager(workspace_root: Path) -> SessionManager:
"""Create a session manager."""
return SessionManager(workspace_root=workspace_root)
class TestMultiBreakpointScenarios:
"""Complex multi-breakpoint debugging scenarios."""
def test_sequential_breakpoints_in_loop(
self, manager: SessionManager, workspace_root: Path
):
"""Test hitting breakpoint multiple times in a loop."""
script = workspace_root / "loop_test.py"
script.write_text(
"""
total = 0
for i in range(5):
total += i
result = total
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# First iteration
request = BreakpointRequest(file=str(script), line=4)
response = manager.run_to_breakpoint(session_id, request)
assert response.hit
assert 'total' in response.locals
# Continue to next breakpoint
response2 = manager.continue_to_breakpoint(session_id, request)
assert response2.hit
manager.end_session(session_id)
def test_breakpoints_across_function_calls(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints in caller and callee."""
script = workspace_root / "function_calls.py"
script.write_text(
"""
def helper(x):
doubled = x * 2
return doubled
def main():
value = 10
result = helper(value)
return result
output = main()
print(output)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# First breakpoint in main
request1 = BreakpointRequest(file=str(script), line=7)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'value' in response1.locals
# Second breakpoint after function call
request2 = BreakpointRequest(file=str(script), line=8)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'result' in response2.locals
manager.end_session(session_id)
def test_breakpoints_in_nested_functions(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints in nested function definitions."""
script = workspace_root / "nested.py"
script.write_text(
"""
def outer(x):
def inner(y):
return y * 2
result = inner(x)
return result
final = outer(10)
print(final)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint in outer function
request1 = BreakpointRequest(file=str(script), line=5)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
# Breakpoint after call
request2 = BreakpointRequest(file=str(script), line=8)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'final' in response2.locals
manager.end_session(session_id)
def test_breakpoints_in_exception_handling(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints in try/except blocks."""
script = workspace_root / "exception.py"
script.write_text(
"""
try:
x = 10
y = 20
z = x + y
except Exception as e:
z = 0
result = z
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint in try block
request1 = BreakpointRequest(file=str(script), line=4)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'x' in response1.locals
assert 'y' in response1.locals
# Breakpoint after try/except
request2 = BreakpointRequest(file=str(script), line=8)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'result' in response2.locals
manager.end_session(session_id)
def test_breakpoints_with_conditional_execution(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints in conditional branches."""
script = workspace_root / "conditional.py"
script.write_text(
"""
x = 10
if x > 5:
result = "large"
else:
result = "small"
final = result
print(final)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint in if branch
request1 = BreakpointRequest(file=str(script), line=4)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
# Breakpoint after conditional
request2 = BreakpointRequest(file=str(script), line=8)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'final' in response2.locals
manager.end_session(session_id)
def test_breakpoints_with_class_instantiation(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints around class instantiation."""
script = workspace_root / "class_test.py"
script.write_text(
"""
class Counter:
def __init__(self, start=0):
self.count = start
def increment(self):
self.count += 1
return self.count
counter = Counter(10)
value = counter.increment()
result = counter.count
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint after instantiation
request1 = BreakpointRequest(file=str(script), line=10)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'counter' in response1.locals
# Breakpoint after method call
request2 = BreakpointRequest(file=str(script), line=11)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'value' in response2.locals
manager.end_session(session_id)
def test_breakpoints_in_list_operations(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints during list operations."""
script = workspace_root / "list_ops.py"
script.write_text(
"""
items = [1, 2, 3, 4, 5]
doubled = [x * 2 for x in items]
filtered = [x for x in doubled if x > 5]
total = sum(filtered)
result = total
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint after comprehension
request1 = BreakpointRequest(file=str(script), line=3)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'doubled' in response1.locals
# Breakpoint after filtering
request2 = BreakpointRequest(file=str(script), line=5)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'total' in response2.locals
manager.end_session(session_id)
def test_breakpoints_with_imports(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints after imports."""
script = workspace_root / "imports.py"
script.write_text(
"""
import math
import json
x = math.sqrt(16)
y = math.pi
data = json.dumps({'x': x, 'y': y})
result = len(data)
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint after math operations
request1 = BreakpointRequest(file=str(script), line=6)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'x' in response1.locals
assert 'y' in response1.locals
# Breakpoint after json operation
request2 = BreakpointRequest(file=str(script), line=7)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'data' in response2.locals
manager.end_session(session_id)
def test_breakpoints_with_string_operations(
self, manager: SessionManager, workspace_root: Path
):
"""Test breakpoints during string manipulations."""
script = workspace_root / "strings.py"
script.write_text(
"""
text = "Hello, World!"
upper = text.upper()
replaced = upper.replace("WORLD", "PYTHON")
words = replaced.split(", ")
result = len(words)
print(result)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Breakpoint after transformations
request1 = BreakpointRequest(file=str(script), line=4)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
assert 'replaced' in response1.locals
# Breakpoint after split
request2 = BreakpointRequest(file=str(script), line=5)
response2 = manager.continue_to_breakpoint(session_id, request2)
assert response2.hit
assert 'words' in response2.locals
manager.end_session(session_id)
def test_step_then_continue_workflow(
self, manager: SessionManager, workspace_root: Path
):
"""Test combining step operations with continue."""
script = workspace_root / "mixed_workflow.py"
script.write_text(
"""
def calculate(a, b):
sum_val = a + b
product = a * b
return sum_val, product
x = 10
y = 20
result = calculate(x, y)
total = result[0] + result[1]
print(total)
"""
)
response = manager.create_session(StartSessionRequest(entry=str(script, pythonPath=sys.executable)))
session_id = response.sessionId
# Run to breakpoint
request1 = BreakpointRequest(file=str(script), line=7)
response1 = manager.run_to_breakpoint(session_id, request1)
assert response1.hit
# Step over
response2 = manager.step_over(session_id)
assert response2.hit
# Continue to next breakpoint
request3 = BreakpointRequest(file=str(script), line=9)
response3 = manager.continue_to_breakpoint(session_id, request3)
assert response3.hit
assert 'result' in response3.locals
manager.end_session(session_id)