假设我有以下类和方法:
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)
如果将类示例放在顶部,您将如何生成单元测试用例?
答案 0 :(得分:2)
您需要的不仅仅是解析树。 (几乎所有没有构建严格的程序分析工具的人都会重复这个错误;你需要更多的机器来做任何真正有趣的事情。这就是为什么编译器不是微不足道的。)
“最简单”的情况需要将要测试的方法的代码解析为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解算器,但我们已经考虑过了。
答案 1 :(得分:0)
您可能希望跳过问题中难以定义且难以定义的部分并查看property based testing。