Compare commits

...

1 Commits

Author SHA1 Message Date
lids bc0c807bfd AI 自动生成测试用例 2026-04-16 09:54:19 +08:00
1 changed files with 80 additions and 0 deletions

80
tests/test_errors.cpp Normal file
View File

@ -0,0 +1,80 @@
#include "gtest/gtest.h"
#include "src/errors.cpp"
#include <iostream>
#include <csignal>
#include <csetjmp>
// 用于捕获信号如SIGSEGV的全局跳转点
static jmp_buf jump_buffer;
// 信号处理函数
void signal_handler(int sig) {
(void)sig; // 抑制未使用参数的警告
longjmp(jump_buffer, 1);
}
// 测试空指针解引用
// 注意:此函数设计为会崩溃,因此测试需要捕获信号或异常。
// 由于直接测试崩溃行为在单元测试中不典型,我们通常期望这类错误在代码审查或静态分析中被发现。
// 这里我们演示一种通过信号处理来“捕获”崩溃的方法,但这更多是演示性质,并非标准单元测试实践。
TEST(ErrorsTest, TestNullPointerTriggersCrash) {
// 安装信号处理器
std::signal(SIGSEGV, signal_handler);
// 设置跳转点。如果setjmp返回0表示首次设置。如果返回非0表示从longjmp跳回。
if (setjmp(jump_buffer) == 0) {
// 尝试执行会崩溃的函数
test_null_pointer();
// 如果执行到这里,说明没有触发崩溃(理论上不应该发生)
FAIL() << "Expected test_null_pointer to cause a segmentation fault, but it did not.";
} else {
// 成功捕获到信号SIGSEGV测试通过
SUCCEED();
}
// 恢复默认信号处理
std::signal(SIGSEGV, SIG_DFL);
}
// 测试数组越界访问
// 与空指针类似数组越界访问也可能导致SIGSEGV或读取到垃圾数据。
// 测试方法同上,使用信号捕获。
TEST(ErrorsTest, TestArrayOutOfBoundsTriggersCrashOrUndefinedBehavior) {
std::signal(SIGSEGV, signal_handler);
if (setjmp(jump_buffer) == 0) {
test_array_out_of_bounds();
// 注意数组越界不一定总是立即导致SIGSEGV可能只是读取到未定义的值。
// 因此,如果执行到这里,我们无法断言测试失败,因为行为是“未定义”的。
// 我们可以输出一个警告,但测试本身不能证明函数正确。
std::cout << "Warning: test_array_out_of_bounds did not cause a segmentation fault.\n";
std::cout << "This does not mean the function is correct; it exhibits undefined behavior.\n";
// 对于未定义行为,我们无法有确定的断言。这里我们选择让测试通过,但附上警告。
// 在实际项目中这类错误应通过代码审查、静态分析或内存检查工具如AddressSanitizer来发现。
SUCCEED();
} else {
// 成功捕获到信号
SUCCEED();
}
std::signal(SIGSEGV, SIG_DFL);
}
// 测试未初始化变量
// 使用未初始化的变量是未定义行为,可能产生任意值,但通常不会直接导致程序崩溃。
// 因此,我们无法编写一个有确定断言的测试来验证其“错误性”。
// 这个测试主要是为了演示和文档化:该函数的行为是未定义的。
// 我们只能运行它,并观察输出(或没有输出)。
TEST(ErrorsTest, TestUninitializedVarExhibitsUndefinedBehavior) {
// 由于行为未定义,我们无法预测输出。
// 我们仅仅调用函数,确保它不会意外崩溃(尽管崩溃也是未定义行为的一种可能)。
// 这里没有断言,因为对于未定义行为,没有“正确”的预期。
// 在实际测试中我们可能希望用工具如Valgrind或MSVC的运行时检查来检测未初始化读取。
EXPECT_NO_FATAL_FAILURE(test_uninitialized_var()); // 至少确保没有gtest致命错误
// 注意EXPECT_NO_FATAL_FAILURE 只检查gtest断言失败不检查程序崩溃。
// 我们可以添加一个简单的输出说明
std::cout << "Note: test_uninitialized_var uses an uninitialized variable. Its behavior is undefined.\n";
}
// 主函数
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}