Back to Repositories

Testing VectorListInfo Wrapper Implementation in OpenAI Gym

This test suite validates the VectorListInfo wrapper functionality in OpenAI Gym’s vector environments, focusing on proper info dictionary conversion to list format and integration with episode statistics recording.

Test Coverage Overview

The test suite provides comprehensive coverage of the VectorListInfo wrapper functionality.

Key areas tested include:
  • Vector environment compatibility validation
  • Info dictionary conversion to list format
  • Episode statistics integration
  • Proper handling of terminated and truncated states
  • Final observation presence verification

Implementation Analysis

The testing approach employs pytest fixtures and assertions to validate the VectorListInfo wrapper’s behavior.

Technical implementation includes:
  • Environment creation with specific parameters (CartPole-v1)
  • Wrapper stacking with RecordEpisodeStatistics
  • Systematic action sampling and state verification
  • Explicit error case testing for non-vector environments

Technical Details

Testing infrastructure includes:
  • pytest as the testing framework
  • OpenAI Gym environment utilities
  • Vector environment configuration (3 environments)
  • Controlled random seed (42) for reproducibility
  • 50-step environment interaction cycle

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Isolated test cases with clear purpose
  • Proper exception handling verification
  • Consistent state validation
  • Structured environment setup and teardown
  • Comprehensive assertion coverage for edge cases

openai/gym

tests/wrappers/test_vector_list_info.py

            
import pytest

import gym
from gym.wrappers import RecordEpisodeStatistics, VectorListInfo

ENV_ID = "CartPole-v1"
NUM_ENVS = 3
ENV_STEPS = 50
SEED = 42


def test_usage_in_vector_env():
    env = gym.make(ENV_ID, disable_env_checker=True)
    vector_env = gym.vector.make(ENV_ID, num_envs=NUM_ENVS, disable_env_checker=True)

    VectorListInfo(vector_env)

    with pytest.raises(AssertionError):
        VectorListInfo(env)


def test_info_to_list():
    env_to_wrap = gym.vector.make(ENV_ID, num_envs=NUM_ENVS, disable_env_checker=True)
    wrapped_env = VectorListInfo(env_to_wrap)
    wrapped_env.action_space.seed(SEED)
    _, info = wrapped_env.reset(seed=SEED)
    assert isinstance(info, list)
    assert len(info) == NUM_ENVS

    for _ in range(ENV_STEPS):
        action = wrapped_env.action_space.sample()
        _, _, terminateds, truncateds, list_info = wrapped_env.step(action)
        for i, (terminated, truncated) in enumerate(zip(terminateds, truncateds)):
            if terminated or truncated:
                assert "final_observation" in list_info[i]
            else:
                assert "final_observation" not in list_info[i]


def test_info_to_list_statistics():
    env_to_wrap = gym.vector.make(ENV_ID, num_envs=NUM_ENVS, disable_env_checker=True)
    wrapped_env = VectorListInfo(RecordEpisodeStatistics(env_to_wrap))
    _, info = wrapped_env.reset(seed=SEED)
    wrapped_env.action_space.seed(SEED)
    assert isinstance(info, list)
    assert len(info) == NUM_ENVS

    for _ in range(ENV_STEPS):
        action = wrapped_env.action_space.sample()
        _, _, terminateds, truncateds, list_info = wrapped_env.step(action)
        for i, (terminated, truncated) in enumerate(zip(terminateds, truncateds)):
            if terminated or truncated:
                assert "episode" in list_info[i]
                for stats in ["r", "l", "t"]:
                    assert stats in list_info[i]["episode"]
                    assert isinstance(list_info[i]["episode"][stats], float)
            else:
                assert "episode" not in list_info[i]