如何在Kotlin中测试递归函数?

问题描述 投票:3回答:2

我正在尝试测试以下tailrec函数:

    private tailrec fun findFixPoint(eps: Double = 5.0, x: Double = 1.0): Double = if (abs(x - cos(x)) < eps) x else findFixPoint(cos(x))

这是我的测试功能:

@Test
fun testNewFeatures(){
    TestCase.assertEquals(0.7390851332151611, findFixPoint())
}

固定点是0.7390851332151611,但是assertEquals返回了我1.0,因为Actualvalue我可以推断出该功能只是一次启动而没有递归。

关于如何正确测试tailrec功能的任何建议?

希望任何人都可以帮助我。谢谢大家。


编辑

[本文的重点是对tailrec函数的测试,以避免出现StackOverflowError,因此,我将在此处发布两个简单的测试,但是sa1nt的答案对于我的问题是正确的,而Benoit的提示是正确的]非常适合简化tailrec测试

因此,以下用于测试StackOverflowError的功能是:

未避免

private fun testStackOverFlow(num : Double): Double = if (num == 10000000000.0) num else testStackOverFlow(num+1)

避免

private tailrec fun testNOTStackOverFlow(num : Double): Double = if (num == 10000000000.0) num else testNOTStackOverFlow(num+1)

测试功能:

@Test
fun testNewFeatures(){

    TestCase.assertEquals(10000000000.0, testStackOverFlow(1.0))
    TestCase.assertEquals(10000000000.0, testNOTStackOverFlow(1.0))
}

谢谢大家的回答。祝你有美好的一天。

testing recursion kotlin tail-recursion
2个回答
4
投票

对于这种方法,Black-box testing似乎是最合适的。基本上,您在不了解内部细节的情况下测试该方法。您只需要检查结果对于给定的输入是否正确,即what方法即可。这就是你所做的。但是无需检查how方法是否得出此结果。

现在假设您完全重写了方法以使用迭代而不是递归:您不需要重写测试,它们都保持有效。


2
投票

TLDR

  1. 将功能更改为:
    tailrec fun findFixPoint(eps: Double = 5.0, x: Double = 1.0): Double =
        if (abs(x - cos(x)) < eps) x
        else findFixPoint(eps, cos(x)) // eps argument added
  1. 和测试:
@Test
fun testNewFeatures(){
    TestCase.assertEquals(0.7390851332151611, findFixPoint(eps = 0.05)) // overriding default eps value
}

详细信息

  1. 在递归调用中显式提供两个参数。否则,cos(x)将用于eps,因为它是第一个参数:private tailrec fun findFixPoint(eps: Double = 5.0, x: Double = 1.0): Double = if (abs(x - cos(x)) < eps) x else findFixPoint(eps, cos(x))

  2. 在测试中,您像findFixPoint()这样调用函数,因此使用默认参数值。因此,if (abs(x - cos(x)) < eps) x else ...eps = 5.0的条件x = 1.0在进入功能后将立即返回x

© www.soinside.com 2019 - 2024. All rights reserved.