#pragma once /** * @file test_framework.h * @brief 轻量级测试框架 * * 提供简单的测试断言和测试注册机制。 */ #include #include #include #include #include #include #include #include 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; struct TestCase { std::string name; std::string suite; TestFunc func; }; std::vector& 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 createTestData(size_t size, u32 seed = 42) { std::vector data(size); for (size_t i = 0; i < size; ++i) { data[i] = static_cast((seed + i) % 256); } return data; } /** * @brief 比较两个数据是否相等 */ inline bool dataEquals(const std::vector& a, const std::vector& b) { if (a.size() != b.size()) return false; return std::equal(a.begin(), a.end(), b.begin()); } } // namespace test } // namespace extra2d