Overview
Standard unit test suite for validating BaseTool implementations, verifying initialization, schema compliance, and environment variable configuration.
Description
This module in the langchain-tests (standard-tests) package defines two test classes: ToolsTests, a base class providing the tool_constructor abstract property, constructor params, invoke params, and a tool fixture, and ToolsUnitTests, which extends it with concrete unit tests. The unit tests verify tool initialization from constructor parameters, initialization from environment variables, presence of a name attribute, presence of an input schema, and that the example invoke params match the declared input schema. The tool_constructor property can be either a BaseTool subclass (type) or a pre-constructed BaseTool instance.
Usage
Import ToolsUnitTests when developing a custom tool integration and you need to verify that the tool initializes correctly, has proper metadata (name, schema), and that example invocation parameters are valid against the schema -- all without making network calls.
Code Reference
Source Location
Signature
class ToolsTests(BaseStandardTests):
"""Base class for testing tools."""
@property
@abstractmethod
def tool_constructor(self) -> type[BaseTool] | BaseTool:
"""Returns a class or instance of a tool to be tested."""
...
@property
def tool_constructor_params(self) -> dict[str, Any]:
"""Returns a dictionary of parameters to pass to the tool constructor."""
...
@property
def tool_invoke_params_example(self) -> dict[str, Any]:
"""Returns a dictionary representing the 'args' of an example tool call."""
...
@pytest.fixture
def tool(self) -> BaseTool:
...
class ToolsUnitTests(ToolsTests):
"""Base class for tools unit tests."""
@property
def init_from_env_params(
self,
) -> tuple[dict[str, str], dict[str, Any], dict[str, Any]]:
...
def test_init(self) -> None: ...
def test_init_from_env(self) -> None: ...
def test_has_name(self, tool: BaseTool) -> None: ...
def test_has_input_schema(self, tool: BaseTool) -> None: ...
def test_input_schema_matches_invoke_params(self, tool: BaseTool) -> None: ...
Import
from langchain_tests.unit_tests.tools import ToolsUnitTests
I/O Contract
Abstract Properties (Must Override)
| Name |
Type |
Required |
Description
|
| tool_constructor |
BaseTool |
Yes |
The BaseTool subclass or instance to test.
|
Optional Properties
| Name |
Type |
Required |
Description
|
| tool_constructor_params |
dict[str, Any] |
No |
Constructor parameters for the tool. Defaults to empty dict. Must be empty if tool_constructor is a BaseTool instance.
|
| tool_invoke_params_example |
dict[str, Any] |
No |
Example args dict for tool invocation (not a ToolCall). Defaults to empty dict.
|
| init_from_env_params |
tuple[dict[str, str], dict[str, Any], dict[str, Any]] |
No |
Tuple of (env_vars, init_args, expected_attrs) for environment variable testing. Defaults to empty dicts (test is skipped).
|
Test Methods
| Test |
Description
|
| test_init |
Verifies the tool can be initialized with the provided constructor params (or used as-is if an instance).
|
| test_init_from_env |
Verifies initialization from environment variables. Skipped if init_from_env_params returns empty dicts. Handles SecretStr unwrapping.
|
| test_has_name |
Verifies the tool has a non-empty name attribute.
|
| test_has_input_schema |
Verifies the tool has a valid input schema via get_input_schema().
|
| test_input_schema_matches_invoke_params |
Verifies that tool_invoke_params_example is valid against the tool's declared input schema.
|
Usage Examples
Basic Usage
from typing import Any
from langchain_core.tools import BaseTool
from langchain_tests.unit_tests.tools import ToolsUnitTests
class TestMyTool(ToolsUnitTests):
@property
def tool_constructor(self) -> type[BaseTool]:
return MyCustomTool
@property
def tool_constructor_params(self) -> dict[str, Any]:
return {"api_key": "test-key"}
@property
def tool_invoke_params_example(self) -> dict[str, Any]:
return {"query": "example search"}
With Pre-constructed Instance
from langchain_core.tools import BaseTool
from langchain_tests.unit_tests.tools import ToolsUnitTests
class TestMyTool(ToolsUnitTests):
@property
def tool_constructor(self) -> BaseTool:
# Return a pre-constructed instance
return MyCustomTool(api_key="test-key")
@property
def tool_invoke_params_example(self) -> dict:
return {"query": "example search"}
With Environment Variable Testing
from langchain_tests.unit_tests.tools import ToolsUnitTests
class TestMyTool(ToolsUnitTests):
@property
def tool_constructor(self):
return MyCustomTool
@property
def tool_constructor_params(self) -> dict:
return {"api_key": "test-key"}
@property
def tool_invoke_params_example(self) -> dict:
return {"query": "example"}
@property
def init_from_env_params(self) -> tuple[dict, dict, dict]:
return (
{"MY_TOOL_API_KEY": "env-api-key"}, # env vars
{}, # init args
{"api_key": "env-api-key"}, # expected attrs
)
Related Pages