java - 基于抽象语法树遍历的代码生成 JUnit

标签 java junit code-generation abstract-syntax-tree

假设我有以下类和方法:

package generation;

class HelloWorld {
  public boolean isEven(int val) {
    if ( (val % 2) == 0)
      return true;
    else
      return false;
  }
}

假设我想生成以下 JUnit 测试:

包生成;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class HelloWorldTest {

    @Test
    public void testIsEven() {
        HelloWorld h = new HelloWorld();
        assertTrue(h.isEven(2));
        assertFalse(h.isEven(1));
    }
} 

给定以下树遍历 Java 语法树的方法: How can I use the java Eclipse Abstract Syntax Tree in a project outside Eclipse? (ie not an eclipse plugin)

给定顶部的类示例,您将如何编写代码生成单元测试用例?

最佳答案

您需要的不仅仅是解析树。 (几乎所有没有构建过严肃的程序分析工具的人都会重复这个错误;你需要更多的机器来做任何真正有趣的事情。这就是为什么编译器不是微不足道的)。

“最简单”的情况需要将要测试的方法的代码解析为 AST,名称/类型解析所有内容以便您了解所有符号的含义(您必须知道整数中的 val),并确定控制流经代码和控制它们的谓词。

有了这些信息,您基本上可以枚举有效的控制流路径,为每个路径获取有关谓词的信息,从而在本质上形成该路径上所有条件的合取。 (在您的示例中,if .. val%2 ... return true; 是一条路径,由 val%2==true 控制)。您需要担心对路径中的副作用如何影响各种谓词进行建模。并且您想要范围内的整数信息(以及字符串和数组的大小等)。

然后对于每个路径,您需要生成一组使路径谓词为真的输入参数;鉴于此谓词可能非常复杂,您可能需要某种 SAT solver .有了路径谓词的解决方案,您现在需要生成对应于测试的 AST(例如,设置变量以使方法参数能够满足谓词;对于简单的整数方程,您可能只生成参数的表达式,就像在您的例子)。最后,将测试调用组装成方法的 AST,插入表示单元测试用例方法的 AST,并漂亮地打印结果。

嗯,这并不难 :-}

我们的 DMS Software Reengineering Toolkit有一个Java front end它将解析 Java,生成 AST,通过方法枚举控制流路径 [这不是那么容易:考虑异常],计算整数变量的范围约束,并为您提供绕过 AST 以提取/构建内容的一般能力你要。尚不包括 SAT 求解器,但我们已经考虑过了。

关于java - 基于抽象语法树遍历的代码生成 JUnit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5404680/

相关文章:

java - 为什么在创建对象的引用时可以使用接口(interface)作为类型?

Java 索引越界异常

java - 如何正确使用鼠标监听器?

java - 在 Ant JUnit 测试运行中仅运行类型的子类

python - 从 Odoo 8 中的另一个模型调用方法

c++ - 在 C++ 中使用 JVM 生成代码

java - 目录浏览器获得 NPE

java - 我需要为 Jersey Rest Web 服务编写 Junit 测试用例..请帮助我或发布示例代码?

java - 当我尝试包含对模拟对象的期望时,此 SecurityException 的原因是什么?

code-generation - 如何编译使用不同版本的代码生成工具创建的 Code Composer 项目?