代码之家  ›  专栏  ›  技术社区  ›  Andrey Tyukin

Scoverage:对“形式无限”`while(true)`loops强制执行100%分支覆盖率

  •  2
  • Andrey Tyukin  · 技术社区  · 7 年前

    下面的简单代码段包含 while -看起来好像无限的循环:

      def findDivisor(n: Int): Int = {
        require(n >= 2)
        var i = 2
        while (true) {
          if (n % i == 0) {
            return i
          } else {
            // do-nothing branch
          }
          i += 1
        }
        // $COVERAGE-OFF$
        throw new Error("unreachable")
        // $COVERAGE-ON$
      }
    

    n

    尽管 $COVERAGE-OFF$ 虽然 计算为分支点,并且 false 以前从未有过分支 return

    移动 // $COVERAGE-OFF$ 在附近,例如在关门前 } 虽然 -身体也没有帮助。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Andrey Tyukin    7 年前

    就把它包起来 while(true) { 将磁头套成一对独立的磁头 $COVERAGE-OFF$ - $COVERAGE-ON$

      def findDivisor(n: Int): Int = {
        require(n >= 2)
        var i = 2
        // $COVERAGE-OFF$
        while (true) {
          // $COVERAGE-ON$
          if (n % i == 0) {
            return i
          } else {
            // do-nothing branch
          }
          i += 1
          // $COVERAGE-OFF$
        }
        throw new Error("unreachable")
        // $COVERAGE-ON$
      }
    

    现在Scoverage确保 while false -分支机构和报告 100% 测试覆盖率,例如在以下简单测试之后:

      "Whatever" should "do something" in {
        MyObjectName.findDivisor(57) should be(3)
      }
    
        2
  •  2
  •   Brian McCutchon    7 年前

    我建议,与其使用编译器,不如用编译器可以理解的术语来提供代码。编译器理解无限递归。

    @tailrec def forever(op: => Unit): Nothing = {
      op
      forever(op)
    }
    
    def findDivisor(n: Int): Int = {
      require(n >= 2)
      var i = 2
      forever {
        if (n % i == 0) {
          return i
        } else {
          // do-nothing branch
        }
        i += 1
      }
    }
    

    forever

    推荐文章