diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp new file mode 100644 index 0000000..a983ef5 --- /dev/null +++ b/tests/test_errors.cpp @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include +#include + +// 由于被测函数会导致程序崩溃或未定义行为, +// 我们使用子进程和信号处理来安全测试 + +// 辅助函数:在子进程中执行可能导致崩溃的函数 +// 并检查是否产生预期的信号 + +// 测试空指针解引用 +TEST(ErrorsTest, NullPointerCausesCrash) { + // 由于空指针解引用会导致程序崩溃, + // 我们通过检查函数是否会导致SIGSEGV来验证 + // 注意:实际测试中可能需要使用fork或特殊处理 + // 这里我们使用EXPECT_DEATH来验证 + EXPECT_DEATH({ + test_null_pointer(); + }, ".*"); +} + +// 测试数组越界访问 +TEST(ErrorsTest, ArrayOutOfBoundsCausesUndefinedBehavior) { + // 数组越界访问是未定义行为,可能不会立即崩溃 + // 但通常会导致内存访问错误 + // 使用EXPECT_DEATH来捕获可能的崩溃 + EXPECT_DEATH({ + test_array_out_of_bounds(); + }, ".*"); +} + +// 测试未初始化变量 +TEST(ErrorsTest, UninitializedVarCausesUndefinedBehavior) { + // 未初始化变量的使用是未定义行为 + // 可能不会立即崩溃,但行为不可预测 + // 这里我们验证函数不会抛出异常(但可能产生任意结果) + EXPECT_NO_THROW({ + test_uninitialized_var(); + }); +} + +// 测试空指针解引用 - 使用信号处理 +TEST(ErrorsTest, NullPointerGeneratesSignal) { + // 验证空指针解引用会产生SIGSEGV信号 + // 使用EXPECT_EXIT来检查退出信号 + EXPECT_EXIT({ + test_null_pointer(); + }, ::testing::KilledBySignal(SIGSEGV), ".*"); +} + +// 测试数组越界 - 使用信号处理 +TEST(ErrorsTest, ArrayOutOfBoundsGeneratesSignal) { + // 数组越界访问可能产生SIGSEGV或SIGABRT + // 使用EXPECT_EXIT来检查退出信号 + EXPECT_EXIT({ + test_array_out_of_bounds(); + }, ::testing::KilledBySignal(SIGSEGV), ".*"); +} + +// 测试未初始化变量 - 验证未定义行为 +TEST(ErrorsTest, UninitializedVarUndefinedBehavior) { + // 未初始化变量的比较结果是未定义的 + // 但函数应该能够执行完成(尽管结果不可预测) + // 这里我们验证函数不会导致程序崩溃 + EXPECT_NO_FATAL_FAILURE({ + test_uninitialized_var(); + }); +} + +// 测试空指针解引用 - 验证崩溃行为 +TEST(ErrorsTest, NullPointerCausesSegfault) { + // 使用ASSERT_DEATH来验证程序会因段错误而终止 + ASSERT_DEATH({ + test_null_pointer(); + }, ""); +} + +// 测试数组越界 - 验证潜在崩溃 +TEST(ErrorsTest, ArrayOutOfBoundsPotentialCrash) { + // 数组越界访问可能导致段错误 + // 使用ASSERT_DEATH来验证 + ASSERT_DEATH({ + test_array_out_of_bounds(); + }, ""); +} + +// 测试未初始化变量 - 验证无崩溃 +TEST(ErrorsTest, UninitializedVarNoCrash) { + // 未初始化变量的使用通常不会导致立即崩溃 + // 但结果是未定义的 + EXPECT_NO_FATAL_FAILURE({ + test_uninitialized_var(); + }); +} + +// 测试空指针解引用 - 验证输出 +TEST(ErrorsTest, NullPointerNoOutput) { + // 由于空指针解引用会导致崩溃, + // 程序不会输出任何内容到标准输出 + testing::internal::CaptureStdout(); + EXPECT_DEATH({ + test_null_pointer(); + }, ""); + std::string output = testing::internal::GetCapturedStdout(); + EXPECT_TRUE(output.empty()); +} + +// 测试数组越界 - 验证输出 +TEST(ErrorsTest, ArrayOutOfBoundsOutput) { + // 数组越界访问可能输出垃圾值或导致崩溃 + testing::internal::CaptureStdout(); + EXPECT_DEATH({ + test_array_out_of_bounds(); + }, ""); + std::string output = testing::internal::GetCapturedStdout(); + // 如果程序崩溃,可能没有输出 + // 如果程序继续执行,可能输出垃圾值 + // 这里我们只验证程序行为 +} + +// 测试未初始化变量 - 验证输出 +TEST(ErrorsTest, UninitializedVarOutput) { + // 未初始化变量的比较结果不确定 + // 如果val > 10为真,会输出"val > 10" + // 否则不会输出任何内容 + testing::internal::CaptureStdout(); + EXPECT_NO_FATAL_FAILURE({ + test_uninitialized_var(); + }); + std::string output = testing::internal::GetCapturedStdout(); + // 输出可能是空字符串或"val > 10" + // 取决于未初始化变量的值 + EXPECT_TRUE(output.empty() || output == "val > 10\n"); +} \ No newline at end of file