Skip to content

Commit c648dc0

Browse files
JackYPCOnlineJack YuanawsarronzastrowmUnshure
authored
feat: add end to end integration test (#30)
* feat: add end to end integration test * feat: add integration tests for the package * feat: remove old test * refactor: refactor the test code with patch api instead of monkeypatch * feat: add STRANDS_ANTHROPIC_BETA environment variable (#34) * feat: add STRANDS_ANTHROPIC_BETA environment variable * docs(readme): document environment variables * Windows: Remove cron tool + document missing tools when on windows (#33) The tool can be imported and run, but without the crontab binary, it's useless on windows * udpate agent system_prompt reference (#35) * chore: explicitly set load_tools_from_directory on Agent initilizations (#38) * chore: explicitly set load_tools_from_directory on Agent initilizations * Update .prompt * Update builder with updates from 0.3.0 SDK (#39) + set minimum sdk version to be 0.3.0 Co-authored-by: Mackenzie Zastrow <[email protected]> * chore: Remove Preview (#40) * deps: bump strangs-agents to v1.0.0 (#41) Co-authored-by: jer <[email protected]> * build(pyproject): update development status classifier (#42) * Use strands logo that looks good in dark & light mode (#44) Similar to strands-agents/sdk-python/pull/475 but using a dedicated github icon. The github icon is the lite logo but copied/renamed to make it dedicated to github * fix: refactor some tests * fix: refactor tests code * fix: make tests more accurate * fix: remove test_custom_load_from_file to avoiding text based response assertion --------- Co-authored-by: Jack Yuan <[email protected]> Co-authored-by: Arron <[email protected]> Co-authored-by: Mackenzie Zastrow <[email protected]> Co-authored-by: Nick Clegg <[email protected]> Co-authored-by: Dean Schmigelski <[email protected]> Co-authored-by: Mackenzie Zastrow <[email protected]> Co-authored-by: Jonathan Segev <[email protected]> Co-authored-by: Jeremiah <[email protected]> Co-authored-by: jer <[email protected]>
1 parent 55910d8 commit c648dc0

File tree

7 files changed

+121
-1
lines changed

7 files changed

+121
-1
lines changed

__init__.py

Whitespace-only changes.

pyproject.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ test = [
143143
"hatch test --cover --cov-report term --cov-report html --cov-report xml {args}"
144144
]
145145

146+
test-integ = [
147+
"hatch test tests_integ {args}"
148+
]
149+
150+
[tool.pytest.ini_options]
151+
testpaths = [
152+
"tests"
153+
]
154+
146155
[tool.mypy]
147156
python_version = "3.10"
148157
warn_return_any = true
@@ -161,7 +170,7 @@ ignore_missing_imports = false
161170

162171
[tool.ruff]
163172
line-length = 120
164-
include = ["src/**/*.py", "tests/**/*.py", "tools/**/*.py"]
173+
include = ["src/**/*.py", "tests/**/*.py", "tools/**/*.py","tests_integ/**/*.py"]
165174

166175
[tool.ruff.lint]
167176
select = [

tests_integ/__init__.py

Whitespace-only changes.

tests_integ/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""Common fixtures for integration tests."""
2+
3+
from pathlib import Path
4+
5+
import pytest
6+
7+
8+
@pytest.fixture
9+
def tmp_file_structure(tmp_path: Path):
10+
"""Creates a temporary directory structure for tool creation and returns paths."""
11+
tools_dir = tmp_path / ".strands" / "tools"
12+
tools_dir.mkdir(parents=True, exist_ok=True)
13+
return {"tools_dir": tools_dir, "root_dir": tmp_path}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import sys
2+
from unittest import mock
3+
4+
from strands import Agent
5+
6+
from strands_agents_builder import strands
7+
8+
9+
def test_build_agent_from_specification_file():
10+
"""Test building agent from specification using semantic creation."""
11+
12+
# Agent specification content
13+
spec_content = """Agent Specification:
14+
- Role: Math Tutor Agent
15+
- Purpose: Help students with basic arithmetic and algebra
16+
- Tools needed: calculator, file_read, current_time
17+
- Create specialized tools for math tutoring
18+
"""
19+
20+
# Simulate: cat agent-spec.txt | strands "Build a specialized agent based on these specifications"
21+
query = f"Build a specialized agent based on these specifications:\n\n{spec_content}"
22+
23+
with mock.patch.object(sys, "argv", ["strands", query]):
24+
strands.main()
25+
26+
# Validate agent
27+
agent = Agent(
28+
load_tools_from_directory=True,
29+
callback_handler=None,
30+
)
31+
32+
# Validate agent was created successfully
33+
assert agent is not None
34+
35+
# Validate agent has exactly 3 specified tools
36+
required_tools = ["calculator", "file_read", "current_time"]
37+
for tool_name in required_tools:
38+
assert hasattr(agent.tool, tool_name), f"Agent missing required tool: {tool_name}"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sys
2+
from unittest import mock
3+
4+
from strands.agent import Agent
5+
6+
from strands_agents_builder import strands
7+
8+
9+
@mock.patch("strands_tools.utils.user_input.get_user_input", return_value="y")
10+
@mock.patch.dict("os.environ", {"STRANDS_TOOL_CONSOLE_MODE": "enabled"})
11+
def test_interactive_model_create_tool_then_validate(mock_get_user_input, capsys, tmp_file_structure):
12+
"""
13+
Test creating a calculator tool via CLI and validating its functionality.
14+
"""
15+
with mock.patch.dict("os.environ", {"STRANDS_TOOLS_DIR": str(tmp_file_structure["tools_dir"])}):
16+
test_query = "create a tool that can only calculate sum of two number called calculator"
17+
18+
with mock.patch.object(sys, "argv", ["strands", test_query]):
19+
strands.main()
20+
21+
agent = Agent(
22+
load_tools_from_directory=True,
23+
)
24+
25+
# assert agent has a tool called calculator
26+
assert hasattr(agent.tool, "calculator"), "Agent should have a 'calculator' tool after creation."
27+
28+
test_cases = [("what is 1 plus 2?", "3"), ("calculate 5 plus 7", "12")]
29+
30+
for question, expected in test_cases:
31+
response = agent(question)
32+
response_str = str(response).lower()
33+
assert expected in response_str, f"Expected '{expected}' in response for '{question}', got '{response_str}'"
34+
35+
# Verify the calculator tool was actually used by checking for toolResults
36+
calculator_used = any(
37+
content.get("toolUse", {}).get("name") == "calculator"
38+
for message in agent.messages
39+
for content in message.get("content", [])
40+
if content.get("toolUse")
41+
)
42+
assert calculator_used, f"Calculator tool should have been used for question: '{question}'"

tests_integ/test_shell_then_exit.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from unittest import mock
2+
3+
from strands_agents_builder import strands
4+
5+
6+
@mock.patch.object(strands, "get_user_input")
7+
@mock.patch.dict("os.environ", {"STRANDS_TOOL_CONSOLE_MODE": "enabled"})
8+
def test_cli_shell_and_interactive_mode(mock_user_input, capsys):
9+
"""Test interactive mode with a shell command."""
10+
11+
user_inputs = ["!echo hello", "exit"]
12+
mock_user_input.side_effect = user_inputs
13+
14+
strands.main()
15+
out = capsys.readouterr().out
16+
17+
assert "hello" in out, "Expected 'hello' (from echo) in output"
18+
assert "thank you for using strands" in out.lower(), "Expected exit message"

0 commit comments

Comments
 (0)