测试框架使用说明
rjsj_test.hpp 是仅头文件(Header-only)的 Mini-Lisp 测试库,提供了针对大作业要求的测试方法和测试数据。
RJSJ_TEST 宏
格式:
RJSJ_TEST(上下文结构体, 测试用例集...)
作用:对 测试用例集 中的每组测试用例,执行 上下文结构体 所定义的求值过程,检查该求值过程是否符合预期。随后,执行 std::exit:若所有测试均通过则程序成功退出,否则程序异常退出。
通常的用法是在 main 函数开头插入 RJSJ_TEST 宏。
上下文结构体
需满足如下概念:
// exposition-only
template <typename T>
concept TestCtx =
std::movable<T> &&
std::default_initializable<T> &&
requires(T ctx, const std::string& str) {
{ ctx.eval(str) } -> std::convertible_to<std::string>;
};
即:
- 可默认构造(
T{}合法); - 可移动(
t = T{}合法); - 对于
std::string类型的input,t.eval(input)的结果可转换到std::string。
对于每组测试用例集,测试框架的行为如下:
- 默认初始化 上下文结构体 对象,记为
ctx; - 对每个测试输入(表达式)
input,执行ctx.eval(input);,结果记为output; - 比较
output与该测试的期望结果是否一致(宽松比较:具体格式不限,浮点数前四位有效数字相同即可)。
测试用例集
rjsj_test 测试框架定义了如下 测试用例集:
Lv2:完成 Lv.2 后,应当通过的测试;Lv2Only:完成 Lv.2 但尚未实现求值环境时,应当通过的测试;Lv3:完成 Lv.3 后,应当通过的测试;Lv4:完成 Lv.4 后,应当通过的测试;Lv5:完成 Lv.5 后,应当通过的测试;Lv5Extra:完成 Lv.5 且实现了内置过程>和*后,应当通过的测试;Lv6:完成 Lv.6 后,应当通过的测试;Lv7:完成 Lv.7 后,应当通过的测试(特殊形式部分);Lv7Lib:完成 Lv.7 后,应当通过的测试(内置过程部分);Sicp:完成 Lv.7 后,应当通过的更多实用测试例子;它们来自《计算机程序的构造和解释(第 2 版)》(Structure and Interpretation of Computer Programs,SICP)的作业题。
在 RJSJ_TEST 宏中指定上述测试用例集名称后,即可进行该用例集的测试。
RJSJ_TEST_NO_EXIT 宏
不定义。
若在引入 rjsj_test.hpp 前定义该宏,则执行 RJSJ_TEST 后程序不会退出,继续执行后续语句。
RJSJ_TEST_ENABLED 宏
默认定义为 1。可通过编译器选项、构建系统等方式定义 RJSJ_TEST 宏为 0,以禁用 RJSJ_TEST 宏的展开操作。