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

时间:2011-03-23 11:40:43

标签: 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)

如果将类示例放在顶部,您将如何生成单元测试用例?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

嗯,这不是那么难: - }

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

答案 1 :(得分:0)

您可能希望跳过问题中难以定义且难以定义的部分并查看property based testing