cdemo/tests/test_errors.cpp

137 lines
4.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");
}