Skip to content

Commit 487a556

Browse files
committed
The tests in robot_driver.py run, and initialisation is done entirely in conftest and test_common
1 parent 36b5c3d commit 487a556

File tree

4 files changed

+491
-396
lines changed

4 files changed

+491
-396
lines changed

ur_robot_driver/test/conftest.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2025, Universal Robots A/S
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are met:
6+
#
7+
# * Redistributions of source code must retain the above copyright
8+
# notice, this list of conditions and the following disclaimer.
9+
#
10+
# * Redistributions in binary form must reproduce the above copyright
11+
# notice, this list of conditions and the following disclaimer in the
12+
# documentation and/or other materials provided with the distribution.
13+
#
14+
# * Neither the name of the {copyright_holder} nor the names of its
15+
# contributors may be used to endorse or promote products derived from
16+
# this software without specific prior written permission.
17+
#
18+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
# POSSIBILITY OF SUCH DAMAGE.
29+
30+
from test_common import (
31+
interfaces,
32+
generate_driver_test_description,
33+
)
34+
import pytest
35+
import launch_pytest
36+
import logging
37+
import rclpy.node
38+
39+
# fixture scope for all fixtures
40+
scope = "function"
41+
42+
43+
# Fixtures for use with the integration tests.
44+
@pytest.fixture(scope=scope, params=["scaled_joint_trajectory_controller"])
45+
def initial_joint_controller(request):
46+
return request.param
47+
48+
49+
@pytest.fixture(scope=scope, params=["", "my_ur_"])
50+
def tf_prefix(request):
51+
return request.param
52+
53+
54+
@pytest.fixture(scope=scope, params=["false", "true"])
55+
def mock_hardware(request):
56+
return request.param
57+
58+
59+
@pytest.fixture(scope=scope, params=[0, 1])
60+
def params(request):
61+
params = [
62+
{"tf_prefix": "", "mock_hardware": "false"},
63+
{"tf_prefix": "my_ur_", "mock_hardware": "true"},
64+
]
65+
return params[request.param]
66+
67+
68+
# Could also be passed like this, but that result in each test being executed 4 times, instead of 2, which seems excessive:
69+
# @launch_pytest.fixture(scope=scope, autouse=True, auto_shutdown=True)
70+
# def launch_description(tf_prefix, mock_hardware):
71+
# return generate_driver_test_description(tf_prefix=tf_prefix, mock_hardware=mock_hardware)
72+
73+
74+
# This only gives 2 exeecutions of each test
75+
@launch_pytest.fixture(scope=scope, autouse=True, auto_shutdown=True)
76+
def launch_description(params):
77+
print("-------------LAUNCHING DRIVER -------------------------------")
78+
tf_prefix = params["tf_prefix"]
79+
mock_hardware = params["mock_hardware"]
80+
return generate_driver_test_description(tf_prefix=tf_prefix, mock_hardware=mock_hardware)
81+
82+
83+
@pytest.fixture(scope=scope)
84+
def rclpy_init():
85+
"""
86+
Initializes and finalizes rclpy.
87+
88+
This ensures that rclpy.init() has been called before, but is not called more than once.
89+
"""
90+
logging.info("Initializing rclpy")
91+
rclpy.init()
92+
93+
yield
94+
95+
logging.info("Shutting down rclpy")
96+
rclpy.shutdown()
97+
98+
99+
@pytest.fixture(scope=scope)
100+
def node(rclpy_init):
101+
"""
102+
Creates a node with a given name.
103+
104+
The name needs to be passed in as a parameter
105+
"""
106+
logging.info("Creating testing node")
107+
rclpy_node = rclpy.node.Node("robot_driver_test")
108+
109+
yield rclpy_node
110+
111+
logging.info("Destroying testing node")
112+
rclpy_node.destroy_node()
113+
114+
115+
@pytest.fixture(scope=scope)
116+
def robot(node, params):
117+
interface = interfaces(node, params)
118+
interface.init_interfaces()
119+
yield interface

ur_robot_driver/test/pytest.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[pytest]
2+
filterwarnings =
3+
ignore::DeprecationWarning

0 commit comments

Comments
 (0)