cdemo/tests/test_errors.cpp

147 lines
4.7 KiB
C++
Raw Permalink 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 "test_errors.h"
// 辅助函数:捕获标准输出
class CaptureOutput {
public:
CaptureOutput() : old_buf(std::cout.rdbuf()) {
std::cout.rdbuf(ss.rdbuf());
}
~CaptureOutput() {
std::cout.rdbuf(old_buf);
}
std::string getOutput() const {
return ss.str();
}
private:
std::stringstream ss;
std::streambuf* old_buf;
};
// 测试 test_null_pointer 函数
// 注意:空指针解引用会导致未定义行为,通常会导致程序崩溃
// 因此测试主要验证函数被调用时不会产生异常输出
TEST(ErrorsTest, test_null_pointer_normal) {
// 由于空指针解引用会导致崩溃,我们使用 EXPECT_DEATH 来验证
// 但注意EXPECT_DEATH 在非调试模式下可能不工作
// 这里我们使用 try-catch 来捕获可能的异常
bool crashed = false;
try {
test_null_pointer();
} catch (...) {
crashed = true;
}
// 在大多数平台上,空指针解引用会导致 SIGSEGV不会被 catch 捕获
// 因此这个测试主要用于验证函数存在且可调用
SUCCEED() << "test_null_pointer called successfully (may crash in real execution)";
}
// 测试 test_null_pointer 在安全环境下的行为
TEST(ErrorsTest, test_null_pointer_safe) {
// 使用信号处理来捕获 SIGSEGV
// 但 Google Test 的 EXPECT_EXIT 可以处理这种情况
// 注意:这个测试在 Windows 上可能不工作
#ifndef _WIN32
EXPECT_EXIT(test_null_pointer(), ::testing::KilledBySignal(SIGSEGV), ".*");
#else
// Windows 下跳过此测试
GTEST_SKIP() << "Skipping on Windows platform";
#endif
}
// 测试 test_array_out_of_bounds 函数
TEST(ErrorsTest, test_array_out_of_bounds_normal) {
// 数组越界访问是未定义行为,可能不会立即崩溃
// 测试函数是否可调用
EXPECT_NO_THROW({
test_array_out_of_bounds();
});
}
// 测试 test_array_out_of_bounds 的输出
TEST(ErrorsTest, test_array_out_of_bounds_output) {
CaptureOutput capture;
test_array_out_of_bounds();
std::string output = capture.getOutput();
// 越界访问 arr[10] 可能输出任意值,但至少应该有输出
EXPECT_FALSE(output.empty());
}
// 测试 test_uninitialized_var 函数
TEST(ErrorsTest, test_uninitialized_var_normal) {
// 未初始化变量是未定义行为
// 测试函数是否可调用
EXPECT_NO_THROW({
test_uninitialized_var();
});
}
// 测试 test_uninitialized_var 的输出
TEST(ErrorsTest, test_uninitialized_var_output) {
CaptureOutput capture;
test_uninitialized_var();
std::string output = capture.getOutput();
// 如果 val > 10 为真,会输出 "val > 10"
// 由于 val 未初始化,结果不确定,但函数应该正常执行
// 这里只验证函数执行完成
SUCCEED() << "test_uninitialized_var executed successfully";
}
// 测试 test_uninitialized_var 的边界情况
TEST(ErrorsTest, test_uninitialized_var_boundary) {
// 多次调用验证行为的一致性
for (int i = 0; i < 10; ++i) {
CaptureOutput capture;
test_uninitialized_var();
std::string output = capture.getOutput();
// 未初始化变量的值不确定,但函数不应崩溃
EXPECT_NO_THROW(test_uninitialized_var());
}
}
// 综合测试:验证所有函数在同一个测试中的行为
TEST(ErrorsTest, test_all_functions_integration) {
// 测试 test_null_pointer
bool null_pointer_called = false;
try {
test_null_pointer();
null_pointer_called = true;
} catch (...) {
null_pointer_called = true;
}
EXPECT_TRUE(null_pointer_called);
// 测试 test_array_out_of_bounds
EXPECT_NO_THROW(test_array_out_of_bounds());
// 测试 test_uninitialized_var
EXPECT_NO_THROW(test_uninitialized_var());
}
// 测试 test_array_out_of_bounds 的边界值
TEST(ErrorsTest, test_array_out_of_bounds_boundary) {
// 测试不同的越界索引
CaptureOutput capture;
test_array_out_of_bounds();
std::string output = capture.getOutput();
// 验证输出不为空
EXPECT_FALSE(output.empty());
// 验证输出是数字arr[10] 的值)
// 注意:由于是未定义行为,输出可能是任何值
// 这里只验证函数执行完成
}
// 测试 test_uninitialized_var 的异常情况
TEST(ErrorsTest, test_uninitialized_var_exception) {
// 未初始化变量可能导致各种行为
// 测试函数在多次调用下的稳定性
for (int i = 0; i < 100; ++i) {
EXPECT_NO_THROW(test_uninitialized_var());
}
}