use*_*558 1 java junit unit-testing functional-testing
函数(无副作用)是一个基本的构建块,但我不知道用Java测试它们的令人满意的方法.
我正在寻找能够更轻松地测试它们的技巧.这是我想要的一个例子:
public void setUp() {
myObj = new MyObject(...);
}
// This is sooo 2009 and not what I want to write:
public void testThatSomeInputGivesExpectedOutput () {
assertEquals(expectedOutput, myObj.myFunction(someInput);
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
// I don't want to repeat/write the following checks to see
// that myFunction is behaving functionally.
assertEquals(expectedOutput, myObj.myFunction(someInput);
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
}
// The following two tests are more in spirit of what I'd like
// to write, but they don't test that myFunction is functional:
public void testThatSomeInputGivesExpectedOutput () {
assertEquals(expectedOutput, myObj.myFunction(someInput);
}
public void testThatSomeOtherInputGivesExpectedOutput () {
assertEquals(expectedOtherOutput, myObj.myFunction(someOtherInput);
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找一些我可以放在测试,MyObject或myFunction上的注释,以使测试框架在我给出的给定输入/输出组合的所有可能的排列中自动重复调用myFunction,或者某些子集可能的排列,以证明该功能是功能性的.
例如,在(仅)两个可能的排列之上是:
和:
我应该只能提供输入/输出对(someInput,expectedOutput)和(someOtherInput,someOtherOutput),框架应该完成剩下的工作.
我没有使用过QuickCheck,但它看起来像是一个非解决方案.它被记录为发电机.我不是在寻找一种方法来为我的函数生成输入,而是一个框架,它允许我声明性地指定我的对象的哪个部分是无副作用的,并使用基于该声明的一些排列来调用我的输入/输出规范.
更新:我不打算验证对象没有任何变化,memoizing函数是这种测试的典型用例,而memoizer实际上改变了它的内部状态.但是,给定输入的输出始终保持不变.
如果你试图测试这些函数是无副作用的,那么用随机参数调用并不会真正削减它.这同样适用于具有已知参数的随机调用序列.或伪随机,随机或固定种子.很有可能只有在随机发生器选择的任何调用序列中才会发生(有害的)副作用.
无论输入是什么,也有可能在您正在进行的任何调用的输出中实际上看不到副作用.它们的副作用可能是你想不到的其他一些相关对象.
如果你想测试这种东西,你真的需要实现一个"白盒"测试,你可以看一下代码并试着找出可能导致(不需要的)副作用的原因并根据这些知识创建测试用例.但我认为更好的方法是仔细的手动代码检查,或使用自动静态代码分析器......如果你能找到一个能为你完成工作的人.
OTOH,如果您已经知道这些功能是无副作用的,那么实施随机测试"以防万一"有点浪费时间,IMO.