Skip to content

[RQT_JTC] add unit tests for parse_joint_limits#2281

Open
lakhmanisahil wants to merge 2 commits intoros-controls:masterfrom
lakhmanisahil:feat/rqt-jtc-unit-tests
Open

[RQT_JTC] add unit tests for parse_joint_limits#2281
lakhmanisahil wants to merge 2 commits intoros-controls:masterfrom
lakhmanisahil:feat/rqt-jtc-unit-tests

Conversation

@lakhmanisahil
Copy link
Copy Markdown

Closes #2253

What this PR does

get_joint_limits() read from a global description variable set only by a ROS topic subscription — impossible to unit test without a live node.

This PR extracts all parsing logic into a new pure function parse_joint_limits(urdf_string, ...) that takes the URDF directly as a string with no ROS dependency. get_joint_limits() becomes a thin wrapper that reads the global and delegates to it. The minidom parsing logic itself is unchanged.

Files changed

File Change
joint_limits_urdf.py Extract parse_joint_limits() from get_joint_limits()
test/test_joint_limits_urdf.py 23 pytest tests, fully ROS-free
test/__init__.py New (marks test dir as Python package)
package.xml Add python3-pytest test dependency

Tests (23 total, all passing)

  • Revolute joint — correct min/max position, velocity, limit flag
  • Continuous joint — defaults to ±π when no bounds given
  • Fixed joints — silently ignored
  • Multiple mixed joints — all handled correctly
  • safety_controller soft limits — narrowed when flag is True, ignored when False
  • Mimic joints — excluded from free_joints
  • Missing <limit> for a required joint → raises with clear message
  • Missing lower/upper on revolute → raises (minidom returns "", our code raises)
  • Missing velocity → raises (same reason — our logic, not minidom's)
Screenshot from 2026-04-04 00-14-26

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 11, 2026

Codecov Report

❌ Patch coverage is 90.84967% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.18%. Comparing base (6c1299f) to head (3bc3ef4).

Files with missing lines Patch % Lines
...t_joint_trajectory_controller/joint_limits_urdf.py 75.43% 9 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2281      +/-   ##
==========================================
+ Coverage   84.72%   85.18%   +0.46%     
==========================================
  Files         153      154       +1     
  Lines       15362    15462     +100     
  Branches     1332     1335       +3     
==========================================
+ Hits        13016    13172     +156     
+ Misses       1858     1798      -60     
- Partials      488      492       +4     
Flag Coverage Δ
unittests 85.18% <90.84%> (+0.46%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ajectory_controller/test/test_joint_limits_urdf.py 100.00% <100.00%> (ø)
...t_joint_trajectory_controller/joint_limits_urdf.py 75.32% <75.43%> (+75.32%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Member

@christophfroehlich christophfroehlich left a comment

Choose a reason for hiding this comment

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

This looks very good, I only have some questions..

Comment on lines +133 to +134
# Joint is not managed by this controller — skip silently
continue
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isn't this a behavior change?

@@ -0,0 +1,339 @@
# Copyright 2024 ros2_control Development Team
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# Copyright 2024 ros2_control Development Team
# Copyright 2026 ros2_control Development Team

Comment on lines +148 to +155
def test_fixed_joint_not_in_result():
result = parse_joint_limits(_robot(_fixed("camera_mount")), [])
assert "camera_mount" not in result


def test_urdf_with_only_fixed_joints_returns_empty_dict():
result = parse_joint_limits(_robot(_fixed("j1"), _fixed("j2")), [])
assert result == {}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isn't the first test irrelevant if the result == {} acc. to the second test?

continue

if name in dependent_joints:
continue
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this line has no coverage acc to codecov, isn't this valid and never reached as per the continue one line above?

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.

rqt_joint_trajectory_controller: Add unit tests

2 participants