【问题标题】:Is it possible to piTest a removed call to scala/MatchError::<init>是否可以对已删除的 scala/MatchError::<init> 调用进行 piTest
【发布时间】:2021-05-12 15:33:05
【问题描述】:

我很想知道是否可以使用 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

【问题讨论】:

    标签: java scala pitest


    【解决方案1】:

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

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

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

    【讨论】:

    • 我可以确认 Pitest 明确不支持 scala,因为字节码中的垃圾突变不会映射回用户可能犯的错误。我相信有一个版本的 Stryker for scala,它可能会提供更好的体验。
    • 啊,有道理!感谢您的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多