是否可以对已删除的 scala/MatchError::<init> 调用进行 piTest

问题描述

我很想知道是否可以使用 Pitest/ScalaCheck 完全测试以下代码

测试方法

  def insertionSort(xs: List[Int]): List[Int] = xs match {
    case Nil => Nil
    case a :: as => insert(a,insertionSort(as))
  }

  private def insert(x: Int,xs: List[Int]): List[Int] = xs match {
    case Nil => List(x)
    case a :: as =>
      if (a >= x) x :: xs
      else a :: insert(x,as)
  }

提供的测试:

@RunWith(classOf[ScalaCheckJUnitPropertiesRunner])
class InsertionSortTests extends Properties("InsertionSortTests") {
   private val nonEmptyIntListGen: Gen[List[Int]] = Gen.nonEmptylistof(Arbitrary.arbitrary[Int])

  property("ordered") = forAll(nonEmptyIntListGen) { (xs: List[Int]) =>
    val sorted = insertionSort(xs)
    xs.nonEmpty ==> xs.indices.tail.forall((i: Int) => sorted(i - 1) <= sorted(i))
  }

  property("permutation") = forAll { (xs: List[Int]) =>
    val sorted = insertionSort(xs)
    def count(a: Int,as: List[Int]) = as.count(_ == a)
    xs.forall((x: Int) => count(x,xs) == count(x,sorted))
  }
}

除以下几行外,我正在获得全面报道:

def insertionSort(xs: List[Int]): List[Int] = xs match {
private def insert(x: Int,xs: List[Int]): List[Int] = xs match {

我在两行都遇到以下错误

1. removed call to scala/MatchError::<init> → NO_COVERAGE

解决方法

scala/MatchError 的调用由编译器在匹配失败的情况下合成(它是对 MatchError 的构造函数的调用,如果没有 case模式匹配适用)。由于您的模式匹配实际上是详尽无遗的,因此匹配不可能失败,因此在 Scala 中无法强制匹配失败(这是假设您使用的是标准库 List;如果您'正在使用您自己的 List 实现,也许它不是 sealed?)

这可能是 Scala 编译器的错误,它为失败的模式匹配生成字节码,而这些匹配不会失败。

我不熟悉pitest,但很可能它不了解Scala(或Scala编译器发出的字节码的更高级别语义);依赖字节码操作的工具可能并不总是像 Java 和 Scala 那样工作。