我一直在尝试创建一个Brainfuck解释器,虽然创建和运行相当简单,但我想能够对其进行测试。然而我无法理解需要编写多少个测试才能测试所有可能的指令组合以确保实现正确性。
显然,Brainfuck的指令集很小,但我不禁思考随着更多指令的添加,您的测试代码将呈指数增长,比通常的测试更甚。
现在,就编写编译器和解释器而言,我是一个非常新手的人,所以我的假设可能完全错误。
基本上,像这样的测试从何处开始呢?
我一直在尝试创建一个Brainfuck解释器,虽然创建和运行相当简单,但我想能够对其进行测试。然而我无法理解需要编写多少个测试才能测试所有可能的指令组合以确保实现正确性。
显然,Brainfuck的指令集很小,但我不禁思考随着更多指令的添加,您的测试代码将呈指数增长,比通常的测试更甚。
现在,就编写编译器和解释器而言,我是一个非常新手的人,所以我的假设可能完全错误。
基本上,像这样的测试从何处开始呢?
测试编译器与测试其他应用程序略有不同,因为只要所有汇编代码版本都能正确执行,编译器产生的不同版本是可以接受的。但如果您只是测试解释器,则基本上与任何其他基于文本的应用程序相同。以下是Unix中心的观点:
test001.bf
test001.0
test001.1
test001.2
(you care about standard error because you want to test your interpreter's error messages)You will need a "run test" script that does something like the following
function fail {
echo "Unexpected differences on $1:"
diff $2 $3
exit 1
}
for testname
do
tmp1=$(tempfile)
tmp2=$(tempfile)
brainfuck $testname.bf < $testname.0 > $tmp1 2> $tmp2
[ cmp -s $testname.1 $tmp1 ] || fail "stdout" $testname.1 $tmp1
[ cmp -s $testname.2 $tmp2 ] || fail "stderr" $testname.2 $tmp2
done
You will find it helpful to have a "create test" script that does something like
brainfuck $testname.bf < $testname.0 > $testname.1 2> $testname.2
You run this only when you're totally confident that the interpreter works for that case.
You keep your test suite under source control.
It's convenient to embellish your test script so you can leave out files that are expected to be empty.
Any time anything changes, you re-run all the tests. You probably also re-run them all nightly via a cron job.
Finally, you want to add enough tests to get good test coverage of your compiler's source code. The quality of coverage tools varies widely, but GNU Gcov is an adequate coverage tool.
test2
目录。软件:实践与经验,2007年4月。(付费软件,不对大众公开——可在http://pobox.com/~flash/Practical_Testing_of_C99.pdf免费获取预印本。)
http://en.wikipedia.org/wiki/Compiler_correctness#Testing(主要由我编写。)
编译器测试参考文献(如果有任何更新,请告知我。)
你可以使用一些已经编写好的应用程序进行测试。
秘诀在于:
软件难以测试是开发人员像1985年一样编写的迹象。很抱歉这么说,但是使用我在这里介绍的三个原则,即使是有行号的BASIC也可以进行单元测试(因为您可以执行“goto variable”来注入依赖项)。