我使用antlr4创建了语法,但我想测试健壮性
有没有自动工具或好方法可以实现快速
感谢:)
由于很难为ANTLR找到真正的单元测试,我写了两篇关于它的文章:
- Lexer的单元测试
- Parser的单元测试
Lexer测试检查给定文本是否被读取并转换为预期的Token序列。例如,避免歧义错误非常有用。
Parser测试获取一个令牌序列(也就是说,它从较小的部分开始),并检查令牌序列是否遍历了预期的规则(java方法)。
我发现为语法创建单元测试的唯一方法是从给定语言的书面规范中创建许多示例。这既不快,也不完整,但我看不出其他办法。
您可能会直接从语法中创建测试用例(为此编写工具并不难)。但请考虑一下。那么你会测试什么?除非使用从早期版本的语法中生成的测试用例,否则单元测试总是会成功的。
一种特殊情况是,为一种已经为另一个语法分析器生成工具编写语法的语言编写语法。在这种情况下,您可以使用原始语法生成测试用例,然后使用这些测试用例来测试新语法的一致性。
然而,我不知道有什么工具可以为您生成测试用例。
更新
同时,我得到了另一个可以进行更好测试的想法:有一个根据语法生成随机句子的句子生成器(我目前正在我的Visual Studio代码ANTLR4扩展中开发一个)。然后可以使用启发式方法来检查生成的句子的有效性:
- 确认基础结构
- 检查必填关键字及其正确顺序
- 请检查标识符和字符串是否有效
- 注意根据语言不同而无效的异常构造
这已经涵盖了语言的大部分内容,但也有局限性。匹配代码和生成代码不是1:1的操作。匹配某些(有效)输入的语法规则可能会产生更多的结果(因此可能会产生无效输入)。
Boris Beizer在其著作《软件测试技术》的一章中谈到了"语法测试"的主题。其基本思想是(在心理上或实际上)采用语法并将其表示为语法图(也称为铁路图)。对于系统测试,该图将被覆盖:输入与元素匹配的好情况,但也包括每个节点的坏情况。迭代和递归调用将像循环一样处理,也就是说,零、一、二、一小于max、max、一高于max迭代的情况(即出现相应的语法元素)。