모의 블랙보드를 활용한 테스트 (Testing with Mock Blackboard)
1. 개요
모의 블랙보드(mock blackboard)를 활용한 테스트는 블랙보드 입력 포트를 통해 매개변수를 수신하는 조건 노드를 격리된 환경에서 검증하는 기법이다. 블랙보드에 테스트 데이터를 직접 설정하여 조건 노드의 입력을 제어하고, 외부 시스템(ROS2 토픽, 서비스 등)과의 의존성 없이 조건 평가 로직만을 독립적으로 테스트할 수 있다.
2. 블랙보드 기반 테스트의 원리
2.1 테스트 구조
[블랙보드에 테스트 값 설정] → [조건 노드 tick] → [반환 상태 검증]
블랙보드는 조건 노드의 입력 포트에 대한 값을 직접 제어할 수 있는 인터페이스를 제공하므로, ROS2 통신 없이도 조건 노드의 논리를 테스트할 수 있다.
2.2 BT::Blackboard의 생성과 조작
auto blackboard = BT::Blackboard::create();
blackboard->set("threshold", 5.0);
blackboard->set("sensor_value", 7.0);
blackboard->set("mode", std::string("autonomous"));
3. 구현 예시
3.1 블랙보드 값 비교 조건 노드의 테스트
class BlackboardConditionTest : public ::testing::Test
{
protected:
void SetUp() override
{
factory_.registerNodeType<IsValueAboveBlackboard>(
"IsValueAbove");
}
BT::BehaviorTreeFactory factory_;
};
TEST_F(BlackboardConditionTest, SuccessWhenAboveThreshold)
{
std::string xml = R"(
<root BTCPP_format="4">
<BehaviorTree ID="Test">
<Condition ID="IsValueAbove"
value="{sensor_value}"
threshold="{threshold}"/>
</BehaviorTree>
</root>
)";
auto blackboard = BT::Blackboard::create();
blackboard->set("sensor_value", 10.0);
blackboard->set("threshold", 5.0);
auto tree = factory_.createTreeFromText(xml, blackboard);
EXPECT_EQ(tree.tickOnce(), BT::NodeStatus::SUCCESS);
}
TEST_F(BlackboardConditionTest, FailureWhenBelowThreshold)
{
auto blackboard = BT::Blackboard::create();
blackboard->set("sensor_value", 3.0);
blackboard->set("threshold", 5.0);
auto tree = factory_.createTreeFromText(xml_, blackboard);
EXPECT_EQ(tree.tickOnce(), BT::NodeStatus::FAILURE);
}
3.2 동적 블랙보드 값 변경 테스트
조건 노드가 블랙보드 값의 변경에 올바르게 반응하는지를 검증한다.
TEST_F(BlackboardConditionTest, ReactsToValueChange)
{
auto blackboard = BT::Blackboard::create();
blackboard->set("value", 3.0);
blackboard->set("threshold", 5.0);
auto tree = factory_.createTreeFromText(xml_, blackboard);
// 초기: 값 < 임계값 → FAILURE
EXPECT_EQ(tree.tickOnce(), BT::NodeStatus::FAILURE);
// 블랙보드 값 변경
blackboard->set("value", 7.0);
// 변경 후: 값 > 임계값 → SUCCESS
EXPECT_EQ(tree.tickOnce(), BT::NodeStatus::SUCCESS);
}
3.3 블랙보드 키 부재 테스트
참조하는 블랙보드 키가 존재하지 않는 경우의 동작을 검증한다.
TEST_F(BlackboardConditionTest, HandlesAbsentKey)
{
auto blackboard = BT::Blackboard::create();
// "threshold" 키를 설정하지 않음
auto tree = factory_.createTreeFromText(xml_, blackboard);
// 키가 없는 경우의 동작 검증
// BehaviorTree.CPP는 기본값이 설정되지 않은 필수 포트에 대해
// 예외를 발생시킬 수 있음
EXPECT_NO_THROW({
auto status = tree.tickOnce();
});
}
3.4 타입 안전성 테스트
블랙보드에 잘못된 타입의 값이 설정된 경우의 동작을 검증한다.
TEST_F(BlackboardConditionTest, HandlesTypeMismatch)
{
auto blackboard = BT::Blackboard::create();
blackboard->set("threshold", std::string("not_a_number"));
auto tree = factory_.createTreeFromText(xml_, blackboard);
// 타입 변환 실패 시의 동작 검증
auto status = tree.tickOnce();
// BehaviorTree.CPP의 타입 변환 규칙에 따라 결과가 결정됨
}
4. 복합 트리에서의 블랙보드 테스트
4.1 블랙보드를 통한 노드 간 데이터 전달 검증
TEST_F(BlackboardIntegrationTest, DataFlowBetweenNodes)
{
std::string xml = R"(
<root BTCPP_format="4">
<BehaviorTree ID="Test">
<Sequence>
<Action ID="ComputeValue"
output="{computed}"/>
<Condition ID="IsValueAbove"
value="{computed}"
threshold="10.0"/>
</Sequence>
</BehaviorTree>
</root>
)";
// ComputeValue가 블랙보드에 기록한 값을
// IsValueAbove가 읽어서 평가하는 흐름을 검증
}
5. 설계 시 고려 사항
5.1 테스트 격리
각 테스트는 독립적인 블랙보드 인스턴스를 사용하여, 이전 테스트의 블랙보드 상태가 후속 테스트에 영향을 미치지 않도록 한다.
5.2 블랙보드의 한계
블랙보드 기반 테스트는 블랙보드 입력 포트만을 테스트할 수 있으며, ROS2 토픽 기반 데이터 수신 로직은 별도로 테스트하여야 한다. 조건 노드의 전체 동작을 검증하려면 블랙보드 테스트와 토픽 기반 테스트를 병행하여야 한다.
5.3 기본값 테스트
입력 포트에 기본값이 정의된 경우, 블랙보드에 값을 설정하지 않았을 때 기본값이 올바르게 적용되는지를 검증한다.
6. 참고 문헌
- Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/
- Google Test 문서. https://google.github.io/googletest/
| 버전 | 날짜 | 변경 사항 |
|---|---|---|
| v0.1 | 2026-04-04 | 초안 작성 |