[开发过程]分支/循环/零零散散的测试

svn update 先.

测试约定

在 test 目录下, 有一坨 test-X.jerry 和 test-X.expect 文件, X=0, 1, 2, 3. 前者是 Jerry 源文件, 而 .expect 文件的则是, 当这个源文件被编译并执行以后应该输出的结果 (确实, 这些例子中没有对输入的测试).

test 目录下还有一个 c 源文件 result-verify.c, 它独立编译后将得到一个用于测试的小工具. 在这个文件中, main 函数会循环 4 次, 每次会编译并执行 Jerry 文件, 然后比较执行输出是否符合预期.

/* 循环体代码 */
/* 拼装文件名 */
sprintf(filename[0], TEST_DIR "test-%d.result", i);
sprintf(filename[1], TEST_DIR "test-%d.expect", i);

/* 编译代码指令 */
sprintf(command, "./Jerry.out " TEST_DIR "test-%d.jerry", i);
execWithCheck(command);
/* 执行代码指令 */
sprintf(command, "./JerryVM.out "
                     TEST_DIR "test-%d.jerry.jry -output %s",
                 i, filename[0]);
execWithCheck(command);

if (NULL == (output = fopen(filename[0], "r"))) {
    fprintf(stderr, "error occurs when accessing %s\n", filename[0]);
    return 1;
}
if (NULL == (expect = fopen(filename[1], "r"))) {
    fprintf(stderr, "error occurs when accessing %s\n", filename[1]);
    fclose(output);
    return 1;
}

int t = verify(output, expect);
if (t) { /* 如果验证失败 */
    fprintf(stderr, "result is WRONG in test-%d\n", i);
    fclose(output);
    fclose(expect);
    return 1;
}
fclose(output);
fclose(expect);

辅助的函数有三个, execWithCheck 执行 system 调用并检查返回值; numericCmp 用于比较两个数值字符串是否相等; verify 对比两个文件. 这里隐含了测试的规则, 那就是测试案例源文件名必须是 test-X.jerry, 而期望的输出文件必须是 test-X.respect. 所以如果要添加测试案例, 请遵循这个规则或者修改 result-verify.c 好了.

测试案例

现有的 test-X 系列测试案例涵盖了基本的运算, 赋值, 逻辑条件短路, 分支和循环, 当然, 还有输出的测试. 不过测试力度比较小 (比如, 死循环的情况就没有测, 在这个测试框架内也没办法测).

另外有 leap.jerry, 可以用来判别输入的年份是否是闰年; bubble-sort.jerry 对输入的实型数进行排序.

这次的更新还包括对分支和循环的一些优化. 在有了测试之后, 优化可以在较为安全的环境下进行. 不过这也引出了一个问题: 运算也可以进行输出对比测试, 而不需关心它们具体生成的指令, 而目前它们的测试两者都有, 如果不放弃直接的指令对比测试, 有其它方法优化吗? 当然, 从现在这个状况看来, 还不如废除原有的指令对比测试, 仅进行输出对比测试.

这个问题我就留个坑在这里吧. (我很懒的, 很多东西都懒得去优化了, 大家自己研究那些虎/鲸等动物系列的书吧 :-)

相关推荐