Compare commits

...

1 Commits

Author SHA1 Message Date
lids b2146f26db AI 自动生成测试用例 2026-04-17 10:31:45 +08:00
1 changed files with 105 additions and 0 deletions

105
tests/test_errors.cpp Normal file
View File

@ -0,0 +1,105 @@
#include "gtest/gtest.h"
#include "src/errors.cpp"
#include <iostream>
#include <csignal>
#include <csetjmp>
// 用于捕获信号和异常的全局变量
static std::jmp_buf jump_buffer;
static volatile std::sig_atomic_t gSignalStatus;
// 信号处理函数
void signal_handler(int signal) {
gSignalStatus = signal;
std::longjmp(jump_buffer, 1);
}
namespace {
// 测试类,用于设置和恢复信号处理器
class SignalGuard {
public:
SignalGuard(int sig, void (*handler)(int)) : m_sig(sig), m_old_handler(std::signal(sig, handler)) {}
~SignalGuard() { std::signal(m_sig, m_old_handler); }
private:
int m_sig;
void (*m_old_handler)(int);
};
// 测试 test_null_pointer 函数
TEST(ErrorsTest, TestNullPointerTriggersSignal) {
// 安装 SIGSEGV 信号处理器
SignalGuard guard(SIGSEGV, signal_handler);
gSignalStatus = 0;
// 使用 setjmp/longjmp 来捕获信号后的跳转
if (setjmp(jump_buffer) == 0) {
// 尝试执行会触发段错误的函数
test_null_pointer();
// 如果执行到这里,说明没有触发信号,测试失败
FAIL() << "Expected test_null_pointer to cause a segmentation fault";
} else {
// 成功捕获到信号
EXPECT_EQ(gSignalStatus, SIGSEGV);
}
}
// 测试 test_array_out_of_bounds 函数
TEST(ErrorsTest, TestArrayOutOfBoundsTriggersSignal) {
// 安装 SIGSEGV 信号处理器
SignalGuard guard(SIGSEGV, signal_handler);
gSignalStatus = 0;
if (setjmp(jump_buffer) == 0) {
test_array_out_of_bounds();
FAIL() << "Expected test_array_out_of_bounds to cause a segmentation fault";
} else {
EXPECT_EQ(gSignalStatus, SIGSEGV);
}
}
// 测试 test_uninitialized_var 函数
// 注意:未初始化变量的行为是未定义的,可能不会崩溃,但结果不可预测。
// 我们无法可靠地测试其具体行为,但可以验证函数调用本身不会导致程序终止(如信号)。
// 然而,为了演示,我们仍然运行它,但不对其输出做任何断言,因为它是未定义的。
TEST(ErrorsTest, TestUninitializedVarRunsWithoutCrash) {
// 这个测试主要是为了确保函数可以被调用,而不导致程序崩溃(尽管行为未定义)。
// 由于未初始化变量的值是未定义的,我们无法断言其具体行为。
// 在某些配置下如调试模式变量可能被初始化为0但这不是保证的。
// 因此,我们只调用函数,不进行断言。
// 注意:这实际上不是一个好的单元测试,因为它没有验证任何确定的行为。
// 它只是为了演示如何“测试”一个具有未定义行为的函数。
// 在实际项目中,这样的函数应该被修复,而不是被测试。
test_uninitialized_var();
// 如果程序执行到这里,说明没有崩溃,测试通过。
// 我们无法对输出做任何有意义的断言。
SUCCEED();
}
// 额外的测试:验证正常数组访问不会崩溃(作为对比)
TEST(ErrorsTest, TestNormalArrayAccessDoesNotCrash) {
int arr[3] = {1, 2, 3};
EXPECT_EQ(arr[0], 1);
EXPECT_EQ(arr[1], 2);
EXPECT_EQ(arr[2], 3);
// 访问有效索引,不应崩溃
SUCCEED();
}
// 额外的测试:验证已初始化的指针解引用不会崩溃(作为对比)
TEST(ErrorsTest, TestValidPointerDereferenceDoesNotCrash) {
int value = 42;
int* p = &value;
EXPECT_EQ(*p, 42);
SUCCEED();
}
// 额外的测试:验证已初始化的变量行为可预测
TEST(ErrorsTest, TestInitializedVarBehaviorIsPredictable) {
int val = 15; // 明确初始化
if (val > 10) {
SUCCEED(); // 条件为真,符合预期
} else {
FAIL() << "Initialized variable should behave predictably";
}
}
}