#include #include #include #include #include // 由于被测函数包含未定义行为(空指针解引用、数组越界、未初始化变量), // 这些函数在正常执行时会导致程序崩溃或不可预测的结果。 // 因此,测试用例的设计侧重于验证这些函数在特定条件下的行为, // 例如通过信号处理或模拟环境来捕获崩溃,或者验证函数不会在非崩溃路径上产生意外输出。 // 注意:直接调用这些函数会导致测试程序崩溃,因此测试用例使用子进程或信号处理来隔离。 // 辅助函数:捕获信号并验证 void signal_handler(int sig) { // 空实现,仅用于捕获信号 } // 测试 test_null_pointer 函数 // 由于该函数会解引用空指针,预期会导致 SIGSEGV 信号 TEST(ErrorTest, NullPointerCausesSegfault) { // 设置信号处理函数 signal(SIGSEGV, signal_handler); // 使用 EXPECT_EXIT 宏来验证程序因 SIGSEGV 而退出 // 注意:由于函数直接崩溃,无法正常返回,因此使用 EXPECT_EXIT EXPECT_EXIT({ test_null_pointer(); }, ::testing::KilledBySignal(SIGSEGV), ""); } // 测试 test_array_out_of_bounds 函数 // 数组越界访问是未定义行为,可能不会立即崩溃,但通常会导致访问非法内存 // 这里我们使用 EXPECT_EXIT 来捕获可能的 SIGSEGV,但并非所有实现都会崩溃 // 因此,我们也可以验证函数不会产生意外输出(如果未崩溃) TEST(ErrorTest, ArrayOutOfBoundsUndefinedBehavior) { // 由于未定义行为,测试可能不稳定。这里我们尝试捕获 SIGSEGV // 如果程序崩溃,测试通过;如果不崩溃,我们至少验证没有异常输出 // 但更合理的做法是使用 EXPECT_EXIT 并允许 SIGSEGV EXPECT_EXIT({ test_array_out_of_bounds(); }, ::testing::KilledBySignal(SIGSEGV), ""); } // 测试 test_uninitialized_var 函数 // 未初始化变量的使用也是未定义行为,可能不会立即崩溃 // 我们使用 EXPECT_EXIT 来捕获可能的 SIGSEGV,但通常不会崩溃 // 因此,我们也可以验证函数不会产生意外输出 TEST(ErrorTest, UninitializedVarUndefinedBehavior) { // 未初始化变量通常不会导致崩溃,但行为不可预测 // 这里我们尝试捕获 SIGSEGV,但预期不会发生 // 更合理的测试是验证函数不会产生异常输出 testing::internal::CaptureStdout(); test_uninitialized_var(); std::string output = testing::internal::GetCapturedStdout(); // 由于 val 未初始化,条件可能为真或假,输出可能为空或包含 "val > 10" // 我们只验证没有异常发生(即函数正常返回) EXPECT_TRUE(true); // 函数正常返回即视为通过 } // 额外的测试:验证函数在非崩溃路径下的行为 // 由于这些函数设计为演示错误,我们也可以测试它们是否按预期产生输出 // 但注意:直接调用会导致崩溃,因此需要特殊处理 // 使用子进程测试 test_null_pointer TEST(ErrorTest, NullPointerSubprocess) { // 使用 EXPECT_EXIT 验证子进程因 SIGSEGV 退出 EXPECT_EXIT({ test_null_pointer(); }, ::testing::KilledBySignal(SIGSEGV), ""); } // 使用子进程测试 test_array_out_of_bounds TEST(ErrorTest, ArrayOutOfBoundsSubprocess) { // 使用 EXPECT_EXIT 验证子进程可能因 SIGSEGV 退出 EXPECT_EXIT({ test_array_out_of_bounds(); }, ::testing::KilledBySignal(SIGSEGV), ""); } // 使用子进程测试 test_uninitialized_var TEST(ErrorTest, UninitializedVarSubprocess) { // 未初始化变量通常不会导致崩溃,但行为不可预测 // 我们只验证子进程正常退出(返回0) EXPECT_EXIT({ test_uninitialized_var(); exit(0); }, ::testing::ExitedWithCode(0), ""); }