Extra2D/Tests/test_framework.h

141 lines
4.2 KiB
C++

#pragma once
/**
* @file test_framework.h
* @brief 轻量级测试框架
*
* 提供简单的测试断言和测试注册机制。
*/
#include <extra2d/core/types.h>
#include <chrono>
#include <cstdio>
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
namespace extra2d {
namespace test {
// ---------------------------------------------------------------------------
// 测试结果统计
// ---------------------------------------------------------------------------
struct TestStats {
int passed = 0;
int failed = 0;
int skipped = 0;
int total() const { return passed + failed + skipped; }
};
// ---------------------------------------------------------------------------
// 测试断言
// ---------------------------------------------------------------------------
#define TEST_ASSERT(condition) \
do { \
if (!(condition)) { \
std::ostringstream _ss; \
_ss << "Assertion failed: " << #condition \
<< " at " << __FILE__ << ":" << __LINE__; \
throw std::runtime_error(_ss.str()); \
} \
} while (0)
#define TEST_ASSERT_EQ(expected, actual) \
do { \
if (!((expected) == (actual))) { \
std::ostringstream _ss; \
_ss << "Assertion failed: expected " << (expected) \
<< " but got " << (actual) \
<< " at " << __FILE__ << ":" << __LINE__; \
throw std::runtime_error(_ss.str()); \
} \
} while (0)
#define TEST_ASSERT_NE(val1, val2) \
do { \
if ((val1) == (val2)) { \
std::ostringstream _ss; \
_ss << "Assertion failed: " << (val1) \
<< " should not equal " << (val2) \
<< " at " << __FILE__ << ":" << __LINE__; \
throw std::runtime_error(_ss.str()); \
} \
} while (0)
#define TEST_ASSERT_TRUE(condition) TEST_ASSERT(condition)
#define TEST_ASSERT_FALSE(condition) TEST_ASSERT(!(condition))
#define TEST_ASSERT_NULL(ptr) TEST_ASSERT((ptr) == nullptr)
#define TEST_ASSERT_NOT_NULL(ptr) TEST_ASSERT((ptr) != nullptr)
#define TEST_ASSERT_GT(val1, val2) TEST_ASSERT((val1) > (val2))
#define TEST_ASSERT_GE(val1, val2) TEST_ASSERT((val1) >= (val2))
#define TEST_ASSERT_LT(val1, val2) TEST_ASSERT((val1) < (val2))
#define TEST_ASSERT_LE(val1, val2) TEST_ASSERT((val1) <= (val2))
// ---------------------------------------------------------------------------
// 测试用例
// ---------------------------------------------------------------------------
using TestFunc = std::function<void()>;
struct TestCase {
std::string name;
std::string suite;
TestFunc func;
};
std::vector<TestCase>& getTestCases();
// ---------------------------------------------------------------------------
// 测试注册器
// ---------------------------------------------------------------------------
class TestRegistrar {
public:
TestRegistrar(const std::string& suite, const std::string& name, TestFunc func);
};
#define TEST(suite, name) \
static void test_##suite##_##name(); \
static extra2d::test::TestRegistrar registrar_##suite##_##name(#suite, #name, test_##suite##_##name); \
static void test_##suite##_##name()
// ---------------------------------------------------------------------------
// 测试运行器
// ---------------------------------------------------------------------------
int runAllTests();
// ---------------------------------------------------------------------------
// 测试工具函数
// ---------------------------------------------------------------------------
/**
* @brief 创建测试数据
* @param size 数据大小
* @param seed 随机种子
* @return 测试数据
*/
inline std::vector<u8> createTestData(size_t size, u32 seed = 42) {
std::vector<u8> data(size);
for (size_t i = 0; i < size; ++i) {
data[i] = static_cast<u8>((seed + i) % 256);
}
return data;
}
/**
* @brief 比较两个数据是否相等
*/
inline bool dataEquals(const std::vector<u8>& a, const std::vector<u8>& b) {
if (a.size() != b.size()) return false;
return std::equal(a.begin(), a.end(), b.begin());
}
} // namespace test
} // namespace extra2d