Java 测试编译器

Java 测试编译器,java,unit-testing,testing,compiler-construction,sablecc,Java,Unit Testing,Testing,Compiler Construction,Sablecc,我目前正在开发一种编译器,它是利用 长话短说,编译器将把规范文件(这是我们正在解析的)和.class文件作为输入,并将插入.class文件字节码,以确保在运行.class文件时,没有违反任何规范(这有点像jml/代码契约!但功能更强大) 我们有几十个系统测试,覆盖了分析阶段的大部分(与确保规范有意义有关,并且它们也与它们应该指定的.class文件一致) 我们将它们分为两组:有效测试和无效测试 有效的测试由源代码文件组成,当我们的编译器编译这些文件时,应该不会弹出任何编译器错误/警告 无效测试由

我目前正在开发一种编译器,它是利用

长话短说,编译器将把规范文件(这是我们正在解析的)和.class文件作为输入,并将插入.class文件字节码,以确保在运行.class文件时,没有违反任何规范(这有点像jml/代码契约!但功能更强大)

我们有几十个系统测试,覆盖了分析阶段的大部分(与确保规范有意义有关,并且它们也与它们应该指定的.class文件一致)

我们将它们分为两组:有效测试和无效测试

  • 有效的测试由源代码文件组成,当我们的编译器编译这些文件时,应该不会弹出任何编译器错误/警告

  • 无效测试由源代码文件组成,当我们的编译器编译这些文件时,应该至少弹出一个编译器错误/警告

在我们处于分析阶段时,这对我们很有帮助。现在的问题是如何测试代码生成阶段。过去,我在一门编译器课程上开发了一个小编译器,并对其进行了系统测试。每个测试将包含该语言的两个源文件和一个
output.txt
。运行测试时,我会编译源文件,然后运行其main方法,检查输出结果是否等于
output.txt
。当然,所有这些都是自动化的

现在,处理这个更大的编译器/字节码指令插入器,事情就不那么容易了。要复制我用简单编译器所做的工作并非易事。我想现在的方法是从系统测试中抽身出来,专注于单元测试


任何编译器开发人员都知道,编译器由许多访问者组成。我不太确定如何进行单元测试。从我看到的情况来看,大多数访问者都在调用一个对应类,该类具有与该访问者相关的方法(我猜其目的是为访问者保留SRP)

我可以采用以下几种技术对编译器进行单元测试:

  • 分别对每个访问者的方法进行单元测试。对于无堆栈的访问者来说,这似乎是个好主意,但对于使用一个(或多个)堆栈的访问者来说,这似乎是个糟糕的主意。然后,我还以传统的方式对标准(read,non-visitor)类中的其他方法进行单元测试

  • 一次性对整个访问者进行单元测试。也就是说,我创建了一棵树,然后访问它。最后,我验证符号表是否正确更新。我不在乎嘲笑它的依赖性

  • 与2相同),但现在模拟访问者的依赖关系

  • 还有什么

  • 我仍然有一个问题,单元测试将与sabbleCC的AST紧密结合(tbh非常难看)


    我们目前没有进行任何新的测试,但我想让火车回到正轨,因为我确信,不测试系统就像喂一只怪物一样,它迟早会在我们最意想不到的时候回来咬我们的屁股-(


    有没有人有过编译器测试方面的经验,可以给我一些关于现在如何进行的建议?我在这里有点迷茫!

    我参与了一个项目,在这个项目中,使用Eclipse编译器将Java AST翻译成另一种语言OpenCL,并且有类似的问题

    我没有神奇的解决方案,但我会分享我的经验,以防有帮助

    您使用预期输出(output.txt)进行测试的技术也是我开始测试的方式,但它成为了测试的绝对维护噩梦我不得不重写所有预期的输出文件,其中有大量的文件。我开始根本不想更改输出,因为我害怕破坏所有的测试(这很糟糕),但最终我放弃了它们,而是对生成的AST进行了测试。这意味着我可以“松散地”测试输出。例如,如果我想测试if语句的生成,我可以在生成的类中只找到一个if语句(我编写了帮助器方法来完成所有这些常见的AST内容),验证一些关于它的事情,然后完成。该测试不关心类的命名方式,也不关心是否有额外的注释或注释。这最终运行得很好,因为测试更加集中。缺点是测试与代码的耦合更紧密,所以如果我想删除Eclipse编译器/AST libra重新编写并使用我需要重写的其他测试。最后,因为代码生成会随着时间的推移而改变,我愿意为此付出代价


    我还严重依赖于集成测试,这些测试实际上是用目标语言编译和运行生成的代码。与单元测试相比,这些类型的测试更多,纯粹是因为它们似乎更有用,并捕获更多的问题


    至于访问者测试,我再次使用它们进行更多的集成风格测试——获取一个非常小/特定的Java源文件,用Eclipse编译器加载它,用它运行我的一个访问者并检查结果。不调用Eclipse编译器的唯一其他测试方法是模拟整个AST,这在大多数情况下都是不可行的访问者非常重要,需要一个完全构造/有效的Java AST,因为他们可以从主类中读取注释。大多数访问者都可以通过这种方式进行测试,因为他们要么生成小的OpenCL代码片段,要么构建一个单元测试可以验证的数据结构

    是的,我所有的测试都与Eclipse编译器紧密耦合。但我们正在编写的实际软件也是如此。使用其他任何东西都意味着