Unit Testing
Closed this issue · 0 comments
Below I have attached my cpp file for which I wish to write a unit test, specifically for the onTick method. This node is supposed to run at the top of the tree inside a reactive fallback to control the current state of the tree eg, localized, e stop, hw failure, sw failure etc. Since it is an essential node in the tree, I wanted to write a unit test for it. The code is from the sample subscriber wrapper provided in the package
`
#include "my_behavior_tree/ok_status.hpp"
using namespace BT;
OKStatus::OKStatus(const std::string& name,
const NodeConfig& conf,
const RosNodeParams& params)
: RosTopicSubNode<std_msgs::msg::String>(name, conf, params)
{
}
BT::PortsList OKStatus::providedPorts()
{
return{InputPort<std::string>("topic_name")};
}
// Check if status is okay or not, if not return failure. Used to control state of the tree
NodeStatus OKStatus::onTick(const std::shared_ptr<std_msgs::msg::String>& last_msg)
{ // TODO - Add multiple state checks
if (last_msg)
{
status = last_msg->data;
if(status =="OK")
{
// RCLCPP_INFO(logger(), "Not in error");
c = 0;
return NodeStatus::SUCCESS;
}
else
{
c =1;
// RCLCPP_INFO(logger(), "In error");
return NodeStatus::FAILURE;
}
}
else
{
if(c ==0)
{
return NodeStatus::SUCCESS;
}
else
{
return NodeStatus::FAILURE;
}
}
}
`
This is the corresponding header file
`
#include "behaviortree_ros2/bt_topic_sub_node.hpp"
#include <std_msgs/msg/string.hpp>
using namespace BT;
class OKStatus: public RosTopicSubNode<std_msgs::msg::String>
{
public:
OKStatus(const std::string& name,
const NodeConfig& conf,
const RosNodeParams& params);
static BT::PortsList providedPorts();
NodeStatus onTick(const std::shared_ptr<std_msgs::msg::String>& last_msg) override;
std::string status;
int c;
};
`
This is the Test method I have written
`
#include <gtest/gtest.h>
#include <ament_index_cpp/get_package_share_directory.hpp>
#include <ament_index_cpp/get_package_prefix.hpp>
#include <rclcpp/rclcpp.hpp>
#include <vector>
#include <string>
#include <fstream>
#include <memory>
#include <utility>
#include <boost/filesystem.hpp>
#include <my_behavior_tree/ok_status.hpp>
using namespace BT;
std_msgs::msg::String createString(const std::string& name)
{
std_msgs::msg::String sample;
sample.data = name;
return sample;
}
class BehaviorTreeTestFixture : public ::testing::Test
{
protected:
std::shared_ptr<BehaviorTreeHandler> bt_handler;
std_msgs::msg::String a;
public:
void SetUp() override
{
bt_handler = std::make_shared<BehaviorTreeHandler>();
a = createString("OK");
}
void TearDown() override
{
bt_handler.reset();
}
};
TEST_F(BehaviorTreeTestFixture, TestSuccess)
{
rclcpp::init(0, nullptr);
auto nh = std::make_shared<rclcpp::Node>("tree_test_node");
RosNodeParams params;
params.nh = nh;
params.default_port_value = "test";
factory.registerNodeType<OKStatus>("OKStatus", params);
OKStatus ok_status("ok_status",NodeConfig(),RosNodeParams());
auto message_ptr = std::make_shared<std_msgs::msg::String>(a);
auto status = ok_status.onTick(message_ptr);
EXPECT_EQ(status, BT::NodeStatus::SUCCESS);
rclcpp::shutdown();
}
`
I am getting the following error when I am running this code
unknown file: Failure C++ exception with description "Both [topic_name] in the InputPort and the RosNodeParams are empty." thrown in the test body.
My idea is to write a unit test specifically for the onTick method only without involving any of the ROS components, but since the OKStatus class is inheriting from the RosTopicSubNode class, I believe that will not be possible without completely re writing the class and separating out the ROS dependency and onTick method.
So I wanted to check if someone has faced a similar problem or has some better suggestions to write a unit test for this method?
I have also tried to load the xml file and also add a tickOnce/tickWhileRunning method but even then I get the same error, however with those cases, the subscriber is actually created but the code eventually crashes at line 181 https://github.com/BehaviorTree/BehaviorTree.ROS2/blob/humble/behaviortree_ros2/include/behaviortree_ros2/bt_topic_sub_node.hpp
Thank you