Magnolia Tech

いつもコードのことばかり考えている人のために。

『実践プロパティベーステスト』の例題をScalaで解いていく その2

blog.magnolia.tech

前回に続いて、ScalaCheckによるプロパティベーステストを書いていきます。

失敗するテストを書く

当然すべてのテストが一度で成功することは有りません(一発で完璧なコードが書けるなら、そもそもテスト書かなくてよくなってしまいます)。

ScalaCheckでテストが失敗するとどうなるか見てみます。

まずは、第2章の例に倣って、テストが失敗するコードを書きます。

def biggest[A](list: List[A]): A =
  list.head

必ず先頭の要素を最大として返却しているので、いかにも失敗しそうです。

対応するテストコードを用意します。標準コレクションのsort機能を使ってソートした結果の最後の要素を最大として取り出します。

property("最大の要素を見つける2") =
  forAll(listOf(arbitrary[Int])): (x: List[Int]) =>
    PbtHelper.biggest(x) == modelBiggest(x)

  def modelBiggest(list: List[Int]): Int = list.sorted.last

実行すると、テストが失敗しました。

sbt:pbt> test
failing seed for Pbt Test.最大の要素を見つける is oSzCiQZYscT-yK1oib2eve7Ls7uAmFa3cNYxkn7YJdK=
[info] ! Pbt Test.最大の要素を見つける: Falsified after 7 passed tests.
[info] > ARG_0: List("0", "1")
[info] > ARG_0_ORIGINAL: List("1", "-1", "1773528742")

ARG_0_ORIGINAL: List("1", "-1", "1773528742")が実際に失敗したテストですが、よりシンプルなARG_0: List("0", "1")というパターンが出てくることで失敗した理由がより分かりやすくなっています。これが収縮です。