diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..4cb68f5 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10.0) +project(test_plan_execute_t1) +include(FetchContent) +if (MSVC) + add_compile_options(/utf-8) +endif() +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) + +include(CTest) +enable_testing() + +add_executable(test_plan_execute_t1 test_app.cpp ../src/app.cpp) + +target_link_libraries(test_plan_execute_t1 gtest gmock gtest_main) +include(GoogleTest) +gtest_discover_tests(test_plan_execute_t1) \ No newline at end of file diff --git a/tests/test_app.cpp b/tests/test_app.cpp new file mode 100644 index 0000000..cfb4588 --- /dev/null +++ b/tests/test_app.cpp @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include "app.hpp" + +// 测试夹具类 +class CmsEngineTest : public ::testing::Test { +protected: + void SetUp() override { + // 每个测试用例执行前初始化引擎 + engine = new CmsEngine(); + } + + void TearDown() override { + delete engine; + } + + CmsEngine* engine; +}; + +// ============================================================ +// ingestEvent 函数测试 +// ============================================================ + +/** + * @requirement(name="战场事件接入", id="REQ-EVENT-INGEST-001") + * 系统需支持从外部事件总线接入原始战场事件,执行基本合法性校验 + * (ID 不能为空、优先级范围检查),通过后存入事件库。 + */ + +// 正常输入测试:有效事件应成功接入 +TEST_F(CmsEngineTest, testIngestEventValid) { + EventRecord event; + event.id = "EVT-001"; + event.priority = 100; + event.status = EventStatus::Pending; + + bool result = engine->ingestEvent(event); + EXPECT_TRUE(result); +} + +// 边界值测试:优先级为 0(最小值) +TEST_F(CmsEngineTest, testIngestEventPriorityMin) { + EventRecord event; + event.id = "EVT-002"; + event.priority = 0; + event.status = EventStatus::Pending; + + bool result = engine->ingestEvent(event); + EXPECT_TRUE(result); +} + +// 边界值测试:优先级为 255(最大值) +TEST_F(CmsEngineTest, testIngestEventPriorityMax) { + EventRecord event; + event.id = "EVT-003"; + event.priority = 255; + event.status = EventStatus::Pending; + + bool result = engine->ingestEvent(event); + EXPECT_TRUE(result); +} + +// 异常输入测试:空 ID 应返回 false +TEST_F(CmsEngineTest, testIngestEventEmptyId) { + EventRecord event; + event.id = ""; + event.priority = 100; + event.status = EventStatus::Pending; + + bool result = engine->ingestEvent(event); + EXPECT_FALSE(result); +} + +// 异常输入测试:优先级超过 255 应返回 false +TEST_F(CmsEngineTest, testIngestEventPriorityOverflow) { + EventRecord event; + event.id = "EVT-004"; + event.priority = 256; + event.status = EventStatus::Pending; + + bool result = engine->ingestEvent(event); + EXPECT_FALSE(result); +} + +// 特殊场景测试:多次接入事件 +TEST_F(CmsEngineTest, testIngestEventMultiple) { + EventRecord event1; + event1.id = "EVT-001"; + event1.priority = 100; + event1.status = EventStatus::Pending; + + EventRecord event2; + event2.id = "EVT-002"; + event2.priority = 200; + event2.status = EventStatus::Pending; + + EXPECT_TRUE(engine->ingestEvent(event1)); + EXPECT_TRUE(engine->ingestEvent(event2)); +} + +// ============================================================ +// processPendingEvents 函数测试 +// ============================================================ + +/** + * @requirement(name="待处理事件处理", id="REQ-EVENT-PROC-001") + * 系统需遍历事件库中所有 Pending 状态的事件,自动将其状态标记为 Generated, + * 并据此生成一个对应的 TaskPlan 草案,实现事件到方案的自动转化。 + */ + +// 正常输入测试:处理待处理事件 +TEST_F(CmsEngineTest, testProcessPendingEventsValid) { + EventRecord event; + event.id = "EVT-001"; + event.priority = 100; + event.status = EventStatus::Pending; + + engine->ingestEvent(event); + + size_t count = engine->processPendingEvents(); + EXPECT_EQ(count, 1); +} + +// 边界值测试:无待处理事件 +TEST_F(CmsEngineTest, testProcessPendingEventsNone) { + size_t count = engine->processPendingEvents(); + EXPECT_EQ(count, 0); +} + +// 边界值测试:事件状态非 Pending +TEST_F(CmsEngineTest, testProcessPendingEventsNonPending) { + EventRecord event; + event.id = "EVT-001"; + event.priority = 100; + event.status = EventStatus::Generated; // 非 Pending 状态 + + engine->ingestEvent(event); + + size_t count = engine->processPendingEvents(); + EXPECT_EQ(count, 0); +} + +// 特殊场景测试:处理多个待处理事件 +TEST_F(CmsEngineTest, testProcessPendingEventsMultiple) { + EventRecord event1; + event1.id = "EVT-001"; + event1.priority = 100; + event1.status = EventStatus::Pending; + + EventRecord event2; + event2.id = "EVT-002"; + event2.priority = 200; + event2.status = EventStatus::Pending; + + engine->ingestEvent(event1); + engine->ingestEvent(event2); + + size_t count = engine->processPendingEvents(); + EXPECT_EQ(count, 2); +} + +// 特殊场景测试:处理事件后状态变为 Generated +TEST_F(CmsEngineTest, testProcessPendingEventsStatusChange) { + EventRecord event; + event.id = "EVT-001"; + event.priority = 100; + event.status = EventStatus::Pending; + + engine->ingestEvent(event); + engine->processPendingEvents(); + + const EventRecord* found = engine->findEventById("EVT-001"); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->status, EventStatus::Generated); +} + +// 特殊场景测试:处理事件后生成对应的 TaskPlan +TEST_F(CmsEngineTest, testProcessPendingEventsPlanGenerated) { + EventRecord event; + event.id = "EVT-001"; + event.priority = 100; + event.status = EventStatus::Pending; + + engine->ingestEvent(event); + engine->processPendingEvents(); + + const std::vector& plans = engine->getAllPlans(); + ASSERT_EQ(plans.size(), 1); + EXPECT_EQ(plans[0].relatedEventId, "EVT-001"); + EXPECT_EQ(plans[0].status, PlanStatus::Drafting); + EXPECT_EQ(plans[0].type, PlanType::Centralized); + EXPECT_FALSE(plans[0].id.empty()); + EXPECT_EQ(plans[0].name, "AutoPlan-EVT-001"); +}