Skip to content

test(pose_tool): cover live-motor read/write actions (68%->91%) - #486

Merged
cagataycali merged 1 commit into
strands-labs:mainfrom
cagataycali:test/pose-tool-motor-actions
Jun 17, 2026
Merged

cagataycali merged 1 commit into
strands-labs:mainfrom
cagataycali:test/pose-tool-motor-actions

Conversation

@cagataycali

Copy link
Copy Markdown
Member

Problem

The pose_tool agent tool routes a dozen actions, but only the pose-management helpers (store/get/list/delete/validate) and the low-level Feetech packet encoding were tested. The dispatch branches that actually talk to the servo bus were entirely uncovered:

  • read_position, read_all
  • store_pose, load_pose
  • move_multiple, incremental_move

That left the action routing, the argument-validation guards, the safety-bounds refusal on load_pose, and the ASCII-only result formatting for every live-motor path unverified. strands_robots/tools/pose_tool.py sat at 68% line coverage.

Change

Add focused behavior tests that exercise each live-motor action with the serial layer mocked, asserting the {status, content} contract on both the success and error paths and pinning the project's ASCII-only output rule:

  • read_position: decode success, missing-motor_name guard, no-response failure
  • read_all: all-six-motor success payload, no-response failure
  • store_pose: missing-name guard, capture-and-persist success, read failure
  • load_pose: drive-to-stored success, safety-bounds validation refusal, unknown-pose error
  • move_multiple: missing-positions guard, multi-motor success
  • incremental_move: missing-args guard, relative-move success, read failure

A small AlwaysReadingSerial fixture answers reads with a decodable Feetech position packet so the read/store success-formatting branches execute -- the MotorController is constructed inside the tool dispatch and cannot be pre-seeded through the existing queue-based fake.

Tests assert observable outputs (status, payload keys, motor set, ASCII) rather than internal state.

Coverage

strands_robots/tools/pose_tool.py: 68% -> 91% (109 -> 31 missing lines).

Tests

MUJOCO_GL=egl python -m pytest tests/tools/test_pose_tool.py -q
43 passed

Test-only change; ruff check, ruff format --check, and mypy on the touched file are clean. No production behavior changes.

The pose_tool dispatch branches that talk to the servo bus (read_position,
read_all, store_pose, load_pose, move_multiple, incremental_move) were
entirely untested -- only the pose-management and packet-encoding helpers
had coverage. This left the action routing, validation guards, and ASCII
result formatting for the live-motor paths unverified.

Add behavior tests that drive every live-motor action with the serial layer
mocked, asserting the {status, content} contract on both success and error
paths and pinning the ASCII-only output rule:

- read_position: decode success, missing-motor_name guard, no-response failure
- read_all: all-six-motor success payload, no-response failure
- store_pose: missing-name guard, capture-and-persist success, read failure
- load_pose: drive-to-stored success, safety-bounds validation refusal,
  unknown-pose error
- move_multiple: missing-positions guard, multi-motor success
- incremental_move: missing-args guard, relative-move success, read failure

A new AlwaysReadingSerial fixture answers reads with a decodable Feetech
position packet so the read/store success-formatting branches execute (the
controller is constructed inside the dispatch and cannot be pre-seeded).

strands_robots/tools/pose_tool.py coverage: 68% -> 91% (109 -> 31 missing).

@yinsong1986 yinsong1986 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Test-only PR that adds focused behavior tests for the previously-uncovered live-motor dispatch branches of pose_tool (read_position, read_all, store_pose, load_pose, move_multiple, incremental_move), with the serial layer mocked. Each action is exercised on both its success and error/validation-guard paths, the {status, content} contract is asserted, and the project's ASCII-only output rule is pinned via _assert_ascii. The assertions match the production strings exactly (e.g. motor_name required, Failed to read current positions, Pose validation failed, the +-signed delta rendering), and the AlwaysReadingSerial / _position_packet fixture correctly decodes to mid-range (0x0800 -> 2048) for the read-success branches. No production code changes; coverage rises 68% -> 91%.

What's good

  • Tests assert observable outputs (status, payload keys, motor set, ASCII) rather than internal state, per AGENTS.md convention 9.
  • Both success and failure paths covered for every action, including the load_pose safety-bounds refusal.
  • ASCII-only rule pinned on every live-motor result; no host paths introduced.

@cagataycali
cagataycali merged commit 5e3fe43 into strands-labs:main Jun 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants