简体   繁体   English

对编译器输出进行单元测试

[英]Unit testing for a compiler output

As part of a university project, we have to write a compiler for a toy language. 作为大学项目的一部分,我们必须为玩具语言编写一个编译器。 In order to do some testing for this, I was considering how best to go about writing something like unit tests. 为了对此进行一些测试,我正在考虑如何最好地编写像单元测试这样的东西。 As the compiler is being written in haskell, Hunit and quickcheck are both available, but perhaps not quite appropriate. 由于编译器是用haskell编写的,因此Hunit和quickcheck都可用,但可能不太合适。

How can we do any kind of non-manual testing? 我们怎么做任何非手动测试? The only idea i've had is effectively compiling to haskell too, seeing what the output is, and using some shell script to compare this to the output of the compiled program - this is quite a bit of work, and isn't too elegant either. 我唯一的想法是有效编译到haskell,看看输出是什么,并使用一些shell脚本将其与编译程序的输出进行比较 - 这是相当多的工作,并不是太优雅无论是。

The unit testing is to help us, and isn't part of assessed work itself. 单元测试是为了帮助我们,而不是评估工作本身的一部分。

This really depends on what parts of the compiler you are writing. 这实际上取决于您编写的编译器的哪些部分。 It is nice if you can keep phases distinct to help isolate problems, but, in any phase, and even at the integration level, it is perfectly reasonable to have unit tests that consist of pairs of source code and hand-compiled code. 如果您可以保持阶段不同以帮助隔离问题,那就太好了,但是,在任何阶段,甚至在集成级别,单元测试由成对的源代码和手工编译的代码组成是完全合理的。 You can start with the simplest legal programs possible, and ensure that your compiler outputs the same thing that you would if compiling by hand. 您可以从最简单的法律程序开始,并确保您的编译器输出与手动编译时相同的内容。

As complexity increases, and hand-compiling becomes unwieldy, it is helpful for the compiler to keep some kind of log of what it has done. 随着复杂性的增加,手工编译变得笨拙,编译器保留其所做的某种日志是有帮助的。 Then you can consult this log to determine whether or not specific transformations or optimizations fired for a given source program. 然后,您可以查阅此日志以确定是否为给定的源程序触发了特定的转换或优化。

Depending on your language, you might consider a generator of random programs from a collection of program fragments (in the QuickCheck vein). 根据您的语言,您可以考虑从程序片段集合中生成随机程序(在QuickCheck中)。 This generator can test your compiler's stability, and ability to deal with potentially unforeseen inputs. 该生成器可以测试编译器的稳定性,以及处理可能无法预料的输入的能力。

The unit tests shall test small piece of code, typically one class or one function. 单元测试应测试一小段代码,通常是一个类或一个函数。 The lexical and semantic analysis will each have their unit tests. 词法和语义分析将各自进行单元测试。 The Intermediate Represetation generator will also have its own tests. Intermediate Represetation生成器也有自己的测试。

A unit test covers a simple test case: it invokes the function to be unit tested in a controlled environment and verify (assert) the result of the function execution. 单元测试涵盖了一个简单的测试用例:它调用在受控环境中进行单元测试的函数,并验证(断言)函数执行的结果。 A unit test usually test one behavior only and has the following structure, called AAA : 单元测试通常只测试一个行为,并具有以下结构,称为AAA:

  • Arrange: create the environment the function will be called in 安排:创建调用函数的环境
  • Act: invoke the function 行动:调用该功能
  • Assert: verify the result 断言:验证结果

Testing becomes more difficult once the output of your program goes to the console (such as standard output). 一旦程序输出进入控制台(例如标准输出),测试就变得更加困难。 Then you have to resort to some external tool, like grep or expect to check the output. 然后你必须使用一些外部工具,如grepexpect检查输出。

Keep the return values from your functions in data structures for as long as possible. 尽可能长时间地保持数据结构中函数的返回值。 If the output of your compiler is, say, assembly code, build a string in memory (or a list of strings) and output it at the last possible moment. 如果编译器的输出是汇编代码,则在内存中构建一个字符串(或字符串列表)并在最后一刻输出它。 That way you can test the contents of the strings more directly and quickly. 这样,您可以更直接,更快速地测试字符串的内容。

Have a look at shelltestrunner . 看看shelltestrunner Here are some example tests . 以下是一些示例测试 It is also being used in this compiler project . 它也在这个编译器项目中使用

One options is to the approach this guy is doing to test real compilers: get together with as many people as you can talk into it and each of you compiles and runs the same set of programs and then compare the outputs. 一个选项是这个人正在做的方法来测试真正的编译器:与你可以对话的人一起聚会,每个人编译并运行相同的程序集,然后比较输出。 Be sure to add every test case you use as more inputs makes it more effective. 请务必添加您使用的每个测试用例,因为更多输入会使其更有效。 A little fun with automation and source control and you can make it fairly easy to maintain. 通过自动化和源代码控制获得一点乐趣,您可以使其易于维护。

Be sure to get it OKed by the prof first but as you will only be sharing test cases and outputs I don't see where he will have much room to object. 一定要先得到教授的确定,但由于你只是分享测试用例和输出,我看不出他有多少空间可以反对。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM