Back to Repositories

Testing Browser Response Parser Implementation in OpenHands

This test suite validates the BrowsingResponseParser functionality in OpenHands, focusing on parsing browser actions and user messages. It ensures proper handling of various input formats and response structures for browser interactions.

Test Coverage Overview

The test suite provides comprehensive coverage of the BrowsingResponseParser class, testing both parse_response and parse_action methods.

  • Tests various input string formats for browser actions
  • Validates message content extraction
  • Covers thought processing and action parsing
  • Tests edge cases with different string formats and delimiters

Implementation Analysis

The implementation uses pytest’s parametrize decorator to create data-driven tests with multiple test cases.

  • Leverages pytest fixtures for test organization
  • Uses parameterized testing for efficient test case handling
  • Implements type hints for better code clarity
  • Separates response parsing from action parsing logic

Technical Details

  • Testing Framework: pytest
  • Key Classes: BrowsingResponseParser, BrowseInteractiveAction
  • Test Methods: parse_response, parse_action
  • Input Validation: String formatting, message extraction, action parsing

Best Practices Demonstrated

The test suite demonstrates strong testing practices through systematic validation of parser functionality.

  • Comprehensive test case coverage
  • Clear test case organization
  • Strong type checking
  • Modular test structure
  • Detailed assertion validation

all-hands-ai/openhands

tests/unit/test_browsing_agent_parser.py

            
import pytest

from openhands.agenthub.browsing_agent.response_parser import (
    BrowseInteractiveAction,
    BrowsingResponseParser,
)


@pytest.mark.parametrize(
    'action_str, expected',
    [
        ("click('81'", "click('81')```"),
        (
            '"We need to search the internet
```goto("google.com")',
            '"We need to search the internet
```goto("google.com")```',
        ),
        ("```click('81'", "```click('81')```"),
        ("click('81')", "click('81')```"),
        (
            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.')",
            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.')```",
        ),
    ],
)
def test_parse_response(action_str: str, expected: str) -> None:
    # BrowsingResponseParser.parse_response
    parser = BrowsingResponseParser()
    response = {'choices': [{'message': {'content': action_str}}]}
    result = parser.parse_response(response)
    assert result == expected


@pytest.mark.parametrize(
    'action_str, expected_browser_actions, expected_thought, expected_msg_content',
    [
        ("click('81')```", "click('81')", '', ''),
        ("```click('81')```", "click('81')", '', ''),
        (
            "We need to perform a click
```click('81')",
            "click('81')",
            'We need to perform a click',
            '',
        ),
        (
            'Tell the user that the city was built in 1751.
```send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
            'send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
            'Tell the user that the city was built in 1751.',
            'Based on the results of my search, the city was built in 1751.',
        ),
        (
            'Tell the user that the city was built in 1751.
```send_msg_to_user("Based on the results of my search, the city was built in 1751.")```',
            'send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
            'Tell the user that the city was built in 1751.',
            'Based on the results of my search, the city was built in 1751.',
        ),
        (
            "Tell the user that the city was built in 1751.
```send_msg_to_user('Based on the results of my search, the city was built in 1751.')```",
            "send_msg_to_user('Based on the results of my search, the city was built in 1751.')",
            'Tell the user that the city was built in 1751.',
            'Based on the results of my search, the city was built in 1751.',
        ),
        (
            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.'))```",
            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.'))",
            '',
            'The server might not be running or accessible. Please check the server status and try again.',
        ),
    ],
)
def test_parse_action(
    action_str: str,
    expected_browser_actions: str,
    expected_thought: str,
    expected_msg_content: str,
) -> None:
    # BrowsingResponseParser.parse_action
    parser = BrowsingResponseParser()
    action = parser.parse_action(action_str)
    assert isinstance(action, BrowseInteractiveAction)
    assert action.browser_actions == expected_browser_actions
    assert action.thought == expected_thought
    assert action.browsergym_send_msg_to_user == expected_msg_content