mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
Update docs
This commit is contained in:
0
unilabos/test/ros/__init__.py
Normal file
0
unilabos/test/ros/__init__.py
Normal file
1
unilabos/test/ros/msgs/__init__.py
Normal file
1
unilabos/test/ros/msgs/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# 消息转换器测试包
|
||||
71
unilabos/test/ros/msgs/test_basic.py
Normal file
71
unilabos/test/ros/msgs/test_basic.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
基本测试
|
||||
|
||||
测试消息转换器的基本功能,包括导入、类型映射等。
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from unilabos.ros.msgs.message_converter import (
|
||||
msg_converter_manager,
|
||||
get_msg_type,
|
||||
get_action_type,
|
||||
get_ros_type_by_msgname,
|
||||
Point3D,
|
||||
Point,
|
||||
Float64,
|
||||
String,
|
||||
Bool,
|
||||
Int32,
|
||||
)
|
||||
|
||||
|
||||
class TestBasicFunctionality(unittest.TestCase):
|
||||
"""测试消息转换器的基本功能"""
|
||||
|
||||
def test_manager_initialization(self):
|
||||
"""测试导入管理器初始化"""
|
||||
self.assertIsNotNone(msg_converter_manager)
|
||||
self.assertTrue(len(msg_converter_manager.list_modules()) > 0)
|
||||
self.assertTrue(len(msg_converter_manager.list_classes()) > 0)
|
||||
|
||||
def test_get_msg_type(self):
|
||||
"""测试获取消息类型"""
|
||||
self.assertEqual(get_msg_type(float), Float64)
|
||||
self.assertEqual(get_msg_type(str), String)
|
||||
self.assertEqual(get_msg_type(bool), Bool)
|
||||
self.assertEqual(get_msg_type(int), Int32)
|
||||
self.assertEqual(get_msg_type(Point3D), Point)
|
||||
|
||||
# 测试错误情况
|
||||
with self.assertRaises(ValueError):
|
||||
get_msg_type(set) # 不支持的类型
|
||||
|
||||
def test_get_action_type(self):
|
||||
"""测试获取动作类型"""
|
||||
float_action = get_action_type(float)
|
||||
self.assertIsNotNone(float_action)
|
||||
self.assertTrue("type" in float_action)
|
||||
self.assertTrue("goal" in float_action)
|
||||
self.assertTrue("feedback" in float_action)
|
||||
|
||||
# 测试错误情况
|
||||
with self.assertRaises(ValueError):
|
||||
get_action_type(set) # 不支持的类型
|
||||
|
||||
def test_get_ros_type_by_msgname(self):
|
||||
"""测试通过消息名称获取ROS类型"""
|
||||
# 测试有效的消息名称
|
||||
point_type = get_ros_type_by_msgname("geometry_msgs/msg/Point")
|
||||
self.assertEqual(point_type, Point)
|
||||
|
||||
# 测试无效的消息名称
|
||||
with self.assertRaises(ValueError):
|
||||
get_ros_type_by_msgname("invalid_format")
|
||||
|
||||
# 不存在的消息类型可能会引发ImportError,但这依赖于运行环境
|
||||
# 因此不进行显式测试
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
131
unilabos/test/ros/msgs/test_conversion.py
Normal file
131
unilabos/test/ros/msgs/test_conversion.py
Normal file
@@ -0,0 +1,131 @@
|
||||
"""
|
||||
转换测试
|
||||
|
||||
测试Python对象和ROS消息之间的转换功能。
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from dataclasses import dataclass
|
||||
|
||||
from unilabos.ros.msgs.message_converter import (
|
||||
convert_to_ros_msg,
|
||||
convert_from_ros_msg,
|
||||
convert_to_ros_msg_with_mapping,
|
||||
convert_from_ros_msg_with_mapping,
|
||||
Point,
|
||||
Float64,
|
||||
String,
|
||||
Point3D,
|
||||
Resource,
|
||||
)
|
||||
|
||||
|
||||
# 定义一些测试数据类
|
||||
@dataclass
|
||||
class TestPoint:
|
||||
x: float = 0.0
|
||||
y: float = 0.0
|
||||
z: float = 0.0
|
||||
|
||||
|
||||
class TestBasicConversion(unittest.TestCase):
|
||||
"""测试基本类型转换"""
|
||||
|
||||
def test_primitive_conversion(self):
|
||||
"""测试原始类型转换"""
|
||||
# Float转换
|
||||
float_value = 3.14
|
||||
ros_float = convert_to_ros_msg(Float64, float_value)
|
||||
self.assertEqual(ros_float.data, float_value)
|
||||
|
||||
# 反向转换
|
||||
py_float = convert_from_ros_msg(ros_float)
|
||||
self.assertEqual(py_float, float_value)
|
||||
|
||||
# 字符串转换
|
||||
str_value = "hello"
|
||||
ros_str = convert_to_ros_msg(String, str_value)
|
||||
self.assertEqual(ros_str.data, str_value)
|
||||
|
||||
# 反向转换
|
||||
py_str = convert_from_ros_msg(ros_str)
|
||||
self.assertEqual(py_str, str_value)
|
||||
|
||||
def test_point_conversion(self):
|
||||
"""测试点类型转换"""
|
||||
# 创建Point3D对象
|
||||
py_point = Point3D(x=1.0, y=2.0, z=3.0)
|
||||
|
||||
# 转换为ROS Point
|
||||
ros_point = convert_to_ros_msg(Point, py_point)
|
||||
self.assertEqual(ros_point.x, py_point.x)
|
||||
self.assertEqual(ros_point.y, py_point.y)
|
||||
self.assertEqual(ros_point.z, py_point.z)
|
||||
|
||||
# 反向转换
|
||||
py_point_back = convert_from_ros_msg(ros_point)
|
||||
self.assertEqual(py_point_back.x, py_point.x)
|
||||
self.assertEqual(py_point_back.y, py_point.y)
|
||||
self.assertEqual(py_point_back.z, py_point.z)
|
||||
|
||||
def test_dataclass_conversion(self):
|
||||
"""测试dataclass转换"""
|
||||
# 创建dataclass
|
||||
test_point = TestPoint(x=1.0, y=2.0, z=3.0)
|
||||
|
||||
# 转换
|
||||
ros_point = convert_to_ros_msg(Point, test_point)
|
||||
self.assertEqual(ros_point.x, test_point.x)
|
||||
self.assertEqual(ros_point.y, test_point.y)
|
||||
self.assertEqual(ros_point.z, test_point.z)
|
||||
|
||||
|
||||
class TestMappingConversion(unittest.TestCase):
|
||||
"""测试映射转换功能"""
|
||||
|
||||
def test_mapping_conversion(self):
|
||||
"""测试带映射的转换"""
|
||||
# 创建测试数据
|
||||
test_data = {
|
||||
"position": {"x": 1.0, "y": 2.0, "z": 3.0},
|
||||
"name": "test_resource",
|
||||
"id": "123",
|
||||
"type": "test_type",
|
||||
}
|
||||
|
||||
# 定义映射
|
||||
mapping = {
|
||||
"id": "id",
|
||||
"name": "name",
|
||||
"type": "type",
|
||||
"pose.position": "position",
|
||||
}
|
||||
|
||||
# 转换为ROS资源
|
||||
ros_resource = convert_to_ros_msg_with_mapping(Resource, test_data, mapping)
|
||||
self.assertEqual(ros_resource.id, "123")
|
||||
self.assertEqual(ros_resource.name, "test_resource")
|
||||
self.assertEqual(ros_resource.type, "test_type")
|
||||
self.assertEqual(ros_resource.pose.position.x, 1.0)
|
||||
self.assertEqual(ros_resource.pose.position.y, 2.0)
|
||||
self.assertEqual(ros_resource.pose.position.z, 3.0)
|
||||
|
||||
# 反向转换
|
||||
reverse_mapping = {
|
||||
"id": "id",
|
||||
"name": "name",
|
||||
"type": "type",
|
||||
"pose.position": "position",
|
||||
}
|
||||
|
||||
py_data = convert_from_ros_msg_with_mapping(ros_resource, reverse_mapping)
|
||||
self.assertEqual(py_data["id"], "123")
|
||||
self.assertEqual(py_data["name"], "test_resource")
|
||||
self.assertEqual(py_data["type"], "test_type")
|
||||
self.assertEqual(py_data["position"].x, 1.0)
|
||||
self.assertEqual(py_data["position"].y, 2.0)
|
||||
self.assertEqual(py_data["position"].z, 3.0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
120
unilabos/test/ros/msgs/test_mapping.py
Normal file
120
unilabos/test/ros/msgs/test_mapping.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""
|
||||
映射测试
|
||||
|
||||
测试消息类型映射和字段映射功能。
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from dataclasses import dataclass
|
||||
|
||||
from unilabos.ros.msgs.message_converter import (
|
||||
_msg_mapping,
|
||||
_action_mapping,
|
||||
_msg_converter,
|
||||
_msg_converter_back,
|
||||
compare_model_fields,
|
||||
Point,
|
||||
Point3D,
|
||||
Float64,
|
||||
String,
|
||||
set_msg_data,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class TestMappingModel:
|
||||
"""用于测试映射的数据类"""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
value: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class TestPointModel:
|
||||
"""用于测试字段比较的点模型"""
|
||||
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
|
||||
|
||||
class TestTypeMapping(unittest.TestCase):
|
||||
"""测试类型映射"""
|
||||
|
||||
def test_msg_mapping(self):
|
||||
"""测试消息类型映射"""
|
||||
self.assertIn(float, _msg_mapping)
|
||||
self.assertEqual(_msg_mapping[float], Float64)
|
||||
|
||||
self.assertIn(str, _msg_mapping)
|
||||
self.assertEqual(_msg_mapping[str], String)
|
||||
|
||||
self.assertIn(Point3D, _msg_mapping)
|
||||
self.assertEqual(_msg_mapping[Point3D], Point)
|
||||
|
||||
def test_action_mapping(self):
|
||||
"""测试动作类型映射"""
|
||||
self.assertIn(float, _action_mapping)
|
||||
self.assertIn("type", _action_mapping[float])
|
||||
self.assertIn("goal", _action_mapping[float])
|
||||
self.assertIn("feedback", _action_mapping[float])
|
||||
self.assertIn("result", _action_mapping[float])
|
||||
|
||||
def test_converter_mapping(self):
|
||||
"""测试转换器映射"""
|
||||
# 测试Python到ROS映射
|
||||
self.assertIn(float, _msg_converter)
|
||||
self.assertIn(Float64, _msg_converter)
|
||||
self.assertIn(String, _msg_converter)
|
||||
self.assertIn(Point, _msg_converter)
|
||||
|
||||
# 测试ROS到Python映射
|
||||
self.assertIn(float, _msg_converter_back)
|
||||
self.assertIn(Float64, _msg_converter_back)
|
||||
self.assertIn(String, _msg_converter_back)
|
||||
self.assertIn(Point, _msg_converter_back)
|
||||
|
||||
|
||||
class TestFieldMapping(unittest.TestCase):
|
||||
"""测试字段映射"""
|
||||
|
||||
def test_compare_model_fields(self):
|
||||
"""测试模型字段比较"""
|
||||
# Point3D和TestPointModel有相同的字段
|
||||
self.assertTrue(compare_model_fields(Point3D, TestPointModel))
|
||||
|
||||
# 与其他类型比较
|
||||
self.assertFalse(compare_model_fields(Point3D, TestMappingModel))
|
||||
self.assertFalse(compare_model_fields(Point3D, float))
|
||||
|
||||
# 类型对象和实例对象比较
|
||||
point = Point3D(x=1.0, y=2.0, z=3.0)
|
||||
self.assertTrue(compare_model_fields(Point3D, type(point)))
|
||||
|
||||
def test_set_msg_data(self):
|
||||
"""测试设置消息数据类型"""
|
||||
# 测试float转换
|
||||
float_value = "3.14"
|
||||
self.assertEqual(set_msg_data("float", float_value), 3.14)
|
||||
self.assertEqual(set_msg_data("double", float_value), 3.14)
|
||||
|
||||
# 测试int转换
|
||||
int_value = "42"
|
||||
self.assertEqual(set_msg_data("int", int_value), 42)
|
||||
|
||||
# 测试bool转换
|
||||
bool_value = "True"
|
||||
self.assertEqual(set_msg_data("bool", bool_value), True)
|
||||
|
||||
# 测试str转换
|
||||
str_value = "hello"
|
||||
self.assertEqual(set_msg_data("str", str_value), "hello")
|
||||
|
||||
# 测试默认转换
|
||||
default_value = 123
|
||||
self.assertEqual(set_msg_data("unknown_type", default_value), "123")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
47
unilabos/test/ros/msgs/test_runner.py
Normal file
47
unilabos/test/ros/msgs/test_runner.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
测试运行器
|
||||
|
||||
运行所有消息转换器的测试用例。
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加项目根目录到路径
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
|
||||
# 导入测试模块
|
||||
from test.ros.msgs.test_basic import TestBasicFunctionality
|
||||
from test.ros.msgs.test_conversion import TestBasicConversion, TestMappingConversion
|
||||
from test.ros.msgs.test_mapping import TestTypeMapping, TestFieldMapping
|
||||
|
||||
|
||||
def run_tests():
|
||||
"""运行所有测试"""
|
||||
# 创建测试加载器
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
# 创建测试套件
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
# 添加测试类
|
||||
suite.addTests(loader.loadTestsFromTestCase(TestBasicFunctionality))
|
||||
suite.addTests(loader.loadTestsFromTestCase(TestBasicConversion))
|
||||
suite.addTests(loader.loadTestsFromTestCase(TestMappingConversion))
|
||||
suite.addTests(loader.loadTestsFromTestCase(TestTypeMapping))
|
||||
suite.addTests(loader.loadTestsFromTestCase(TestFieldMapping))
|
||||
|
||||
# 创建测试运行器
|
||||
runner = unittest.TextTestRunner(verbosity=2)
|
||||
|
||||
# 运行测试
|
||||
result = runner.run(suite)
|
||||
|
||||
# 返回结果
|
||||
return result.wasSuccessful()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = run_tests()
|
||||
sys.exit(not success)
|
||||
Reference in New Issue
Block a user