137 lines
4.4 KiB
C++
137 lines
4.4 KiB
C++
|
|
#include <gtest/gtest.h>
|
|||
|
|
#include <gmock/gmock.h>
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <sstream>
|
|||
|
|
#include <csignal>
|
|||
|
|
#include <csetjmp>
|
|||
|
|
|
|||
|
|
// 由于被测函数会导致程序崩溃或未定义行为,
|
|||
|
|
// 我们使用子进程和信号处理来安全测试
|
|||
|
|
|
|||
|
|
// 辅助函数:在子进程中执行可能导致崩溃的函数
|
|||
|
|
// 并检查是否产生预期的信号
|
|||
|
|
|
|||
|
|
// 测试空指针解引用
|
|||
|
|
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");
|
|||
|
|
}
|