Compare commits

...

1 Commits

Author SHA1 Message Date
lids 3851b2eebf AI 自动生成测试用例 2026-06-02 15:44:22 +08:00
2 changed files with 349 additions and 0 deletions

25
tests/CMakeLists.txt Normal file
View File

@ -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)

324
tests/test_app.cpp Normal file
View File

@ -0,0 +1,324 @@
#include <gtest/gtest.h>
#include "app.hpp"
#include <string>
#include <vector>
// ============================================================
// 测试夹具CmsEngineTest
// ============================================================
class CmsEngineTest : public ::testing::Test {
protected:
CmsEngine engine;
void SetUp() override {
// 初始化一些事件用于测试
EventRecord evt1;
evt1.id = "EVT-001";
evt1.priority = 100;
evt1.status = EventStatus::Pending;
engine.ingestEvent(evt1);
EventRecord evt2;
evt2.id = "EVT-002";
evt2.priority = 200;
evt2.status = EventStatus::Pending;
engine.ingestEvent(evt2);
EventRecord evt3;
evt3.id = "EVT-003";
evt3.priority = 50;
evt3.status = EventStatus::Generated; // 非 Pending 状态
engine.ingestEvent(evt3);
}
void TearDown() override {
// 清理工作(如果需要)
}
};
// ============================================================
// 测试用例processPendingEvents
// ============================================================
/**
* @requirement(name="待处理事件处理", id="REQ-EVENT-PROC-001")
* Pending Generated
* TaskPlan
*/
// 正常输入测试:处理所有 Pending 事件
TEST_F(CmsEngineTest, testProcessPendingEventsNormal) {
// 执行:处理待处理事件
size_t processedCount = engine.processPendingEvents();
// 验证:应该处理了 2 个 Pending 事件EVT-001 和 EVT-002
EXPECT_EQ(processedCount, 2);
// 验证:事件状态已更新
const EventRecord* evt1 = engine.findEventById("EVT-001");
ASSERT_NE(evt1, nullptr);
EXPECT_EQ(evt1->status, EventStatus::Generated);
const EventRecord* evt2 = engine.findEventById("EVT-002");
ASSERT_NE(evt2, nullptr);
EXPECT_EQ(evt2->status, EventStatus::Generated);
// 验证:非 Pending 事件状态不变
const EventRecord* evt3 = engine.findEventById("EVT-003");
ASSERT_NE(evt3, nullptr);
EXPECT_EQ(evt3->status, EventStatus::Generated); // 原本就是 Generated
// 验证:生成了对应的 TaskPlan
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 2);
// 验证第一个方案的属性
EXPECT_EQ(plans[0].name, "AutoPlan-EVT-001");
EXPECT_EQ(plans[0].type, PlanType::Centralized);
EXPECT_EQ(plans[0].status, PlanStatus::Drafting);
EXPECT_EQ(plans[0].relatedEventId, "EVT-001");
EXPECT_FLOAT_EQ(plans[0].resourceQuota, 0.5);
EXPECT_EQ(plans[0].constraints, "自动生成约束");
// 验证第二个方案的属性
EXPECT_EQ(plans[1].name, "AutoPlan-EVT-002");
EXPECT_EQ(plans[1].relatedEventId, "EVT-002");
}
// 边界值测试:没有 Pending 事件
TEST_F(CmsEngineTest, testProcessPendingEventsNoPending) {
// 先处理所有 Pending 事件
engine.processPendingEvents();
// 再次调用,应该没有 Pending 事件了
size_t processedCount = engine.processPendingEvents();
// 验证:处理数量为 0
EXPECT_EQ(processedCount, 0);
// 验证:方案数量没有增加
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 2); // 仍然是第一次处理生成的 2 个方案
}
// 边界值测试:事件列表为空
TEST_F(CmsEngineTest, testProcessPendingEventsEmptyEvents) {
// 创建一个新的空引擎
CmsEngine emptyEngine;
// 执行:处理待处理事件
size_t processedCount = emptyEngine.processPendingEvents();
// 验证:处理数量为 0
EXPECT_EQ(processedCount, 0);
// 验证:方案列表为空
const std::vector<TaskPlan>& plans = emptyEngine.getAllPlans();
EXPECT_TRUE(plans.empty());
}
// 特殊场景测试:多次调用 processPendingEvents
TEST_F(CmsEngineTest, testProcessPendingEventsMultipleCalls) {
// 第一次调用
size_t firstCount = engine.processPendingEvents();
EXPECT_EQ(firstCount, 2);
// 第二次调用(已经没有 Pending 事件了)
size_t secondCount = engine.processPendingEvents();
EXPECT_EQ(secondCount, 0);
// 验证:方案数量为 2只有第一次生成的
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 2);
}
// ============================================================
// 测试用例findEventById
// ============================================================
/**
* @requirement(name="事件查询", id="REQ-EVENT-QUERY-001")
* ID
* nullptr
*/
// 正常输入测试:查找存在的事件
TEST_F(CmsEngineTest, testFindEventByIdNormal) {
const EventRecord* evt = engine.findEventById("EVT-001");
// 验证:找到事件
ASSERT_NE(evt, nullptr);
EXPECT_EQ(evt->id, "EVT-001");
EXPECT_EQ(evt->priority, 100);
EXPECT_EQ(evt->status, EventStatus::Pending);
}
// 边界值测试:查找不存在的事件
TEST_F(CmsEngineTest, testFindEventByIdNotFound) {
const EventRecord* evt = engine.findEventById("NONEXISTENT");
// 验证:返回 nullptr
EXPECT_EQ(evt, nullptr);
}
// 边界值测试:查找空字符串 ID
TEST_F(CmsEngineTest, testFindEventByIdEmptyId) {
const EventRecord* evt = engine.findEventById("");
// 验证:返回 nullptr因为事件 ID 不能为空,所以不会有空 ID 的事件)
EXPECT_EQ(evt, nullptr);
}
// 边界值测试:查找特殊字符 ID
TEST_F(CmsEngineTest, testFindEventByIdSpecialChars) {
const EventRecord* evt = engine.findEventById("EVT-@#$");
// 验证:返回 nullptr不存在该事件
EXPECT_EQ(evt, nullptr);
}
// 特殊场景测试:查找已处理的事件(状态已改变)
TEST_F(CmsEngineTest, testFindEventByIdAfterProcessing) {
// 先处理事件
engine.processPendingEvents();
// 查找已处理的事件
const EventRecord* evt = engine.findEventById("EVT-001");
// 验证:找到事件,且状态已更新
ASSERT_NE(evt, nullptr);
EXPECT_EQ(evt->id, "EVT-001");
EXPECT_EQ(evt->status, EventStatus::Generated);
}
// ============================================================
// 测试用例createTaskPlan
// ============================================================
/**
* @requirement(name="任务方案创建", id="REQ-PLAN-CREATE-001")
* ID
*
*/
// 正常输入测试:创建有效的任务方案
TEST_F(CmsEngineTest, testCreateTaskPlanNormal) {
TaskPlan plan;
plan.name = "Test Plan";
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
plan.resourceQuota = 0.8;
plan.constraints = "测试约束";
// 执行:创建任务方案
bool result = engine.createTaskPlan(plan);
// 验证:创建成功
EXPECT_TRUE(result);
// 验证:方案 ID 已被填充(格式为 ID-xxxxx
EXPECT_FALSE(plan.id.empty());
EXPECT_EQ(plan.id.substr(0, 3), "ID-");
EXPECT_EQ(plan.id.length(), 8); // "ID-" + 5 位数字
// 验证:创建时间已被填充
// 由于 createTime 是 system_clock::time_point我们无法直接比较
// 但可以确认它已经被设置(不为默认值)
auto now = std::chrono::system_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::seconds>(now - plan.createTime).count();
EXPECT_LE(diff, 1); // 创建时间应该在 1 秒内
// 验证:方案已被添加到方案库
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].id, plan.id);
EXPECT_EQ(plans[0].name, "Test Plan");
EXPECT_EQ(plans[0].type, PlanType::Centralized);
EXPECT_EQ(plans[0].status, PlanStatus::Drafting);
EXPECT_FLOAT_EQ(plans[0].resourceQuota, 0.8);
EXPECT_EQ(plans[0].constraints, "测试约束");
}
// 边界值测试:创建名称为空的方案
TEST_F(CmsEngineTest, testCreateTaskPlanEmptyName) {
TaskPlan plan;
plan.name = ""; // 空名称
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
// 执行:创建任务方案
bool result = engine.createTaskPlan(plan);
// 验证:创建失败
EXPECT_FALSE(result);
// 验证:方案 ID 未被填充
EXPECT_TRUE(plan.id.empty());
// 验证:方案未被添加到方案库
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_TRUE(plans.empty());
}
// 边界值测试:创建名称为空格的方案
TEST_F(CmsEngineTest, testCreateTaskPlanSpaceName) {
TaskPlan plan;
plan.name = " "; // 空格名称
plan.type = PlanType::Centralized;
plan.status = PlanStatus::Drafting;
// 执行:创建任务方案
bool result = engine.createTaskPlan(plan);
// 验证:创建成功(因为空格不是空字符串)
EXPECT_TRUE(result);
// 验证:方案已被添加到方案库
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 1);
EXPECT_EQ(plans[0].name, " ");
}
// 特殊场景测试:创建多个方案,验证 ID 自增
TEST_F(CmsEngineTest, testCreateTaskPlanMultiplePlans) {
TaskPlan plan1;
plan1.name = "Plan 1";
engine.createTaskPlan(plan1);
TaskPlan plan2;
plan2.name = "Plan 2";
engine.createTaskPlan(plan2);
TaskPlan plan3;
plan3.name = "Plan 3";
engine.createTaskPlan(plan3);
// 验证:生成了 3 个方案
const std::vector<TaskPlan>& plans = engine.getAllPlans();
EXPECT_EQ(plans.size(), 3);
// 验证ID 自增ID-00001, ID-00002, ID-00003
EXPECT_EQ(plans[0].id, "ID-00001");
EXPECT_EQ(plans[1].id, "ID-00002");
EXPECT_EQ(plans[2].id, "ID-00003");
// 验证:名称正确
EXPECT_EQ(plans[0].name, "Plan 1");
EXPECT_EQ(plans[1].name, "Plan 2");
EXPECT_EQ(plans[2].name, "Plan 3");
}
// 特殊场景测试:创建方案后,通过 findPlanById 验证
TEST_F(CmsEngineTest, testCreateTaskPlanAndFindById) {
TaskPlan plan;
plan.name = "Findable Plan";
engine.createTaskPlan(plan);
// 通过 ID 查找方案
const TaskPlan* foundPlan = engine.findPlanById(plan.id);
// 验证:找到方案
ASSERT_NE(foundPlan, nullptr);
EXPECT_EQ(foundPlan->id, plan.id);
EXPECT_EQ(foundPlan->name, "Findable Plan");
}