假设我有以下类和方法:
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/