by shigemk2

当面は技術的なことしか書かない

property based testingの話 まとめ #関数型Scala

connpass.com

Property Based Testing - scalapropsとscalacheckとその他色々

内容

  • property based testing と scalacheckの説明
  • scalacheckその不満点
  • scalaprops
  • Haskellの、その他様々な使い方の紹介

github.com

http://scalatest.org/user_guide/property_based_testing

  • Property = 性質
  • テストデータを半自動生成
  • 証明と普通のテストの中間のような?

  • 半自動 vs 全自動は後述

QuickCheck: Automatic testing of Haskell programs | Hackage

ScalaCheck: The Definitive Guide (English Edition)

ScalaCheck: The Definitive Guide (English Edition)

Scalacheckとは

  • 古くからある
  • specs2とかscalatestとかと組み合わせられる
  • 本体のテストにも使われる
  • Scala界隈唯一のProperty Based Testのライブラリ

  • D社でも使っていて、jsonやmsgpackのシリアライズやデシリアライズなどで

  • scalacheckのテストの書き方の例

forAll { l: List[String] =>
  l.reverse.reverse == l
}
  • 事前に関数を定義しておけば、任意の型の値が生成可能
  • List[String] は半自動で生成

Scalacheckがあるんだけど、不満があったので再発明したくなった

  • ScalazでもScalacheckをつかっている
  • 誰よりもScalacheckぽい

不満

  • CoArbitraryがない
  • 巨大な値を生成してしまうことがあり、テストが終わらないときの対策
  • seedを指定してランダムだけど予測可能なテスト
  • GenとArbitraryがあまり意味ない
  • ScalazのTypeclassの階層と重複テスト

  • 型クラスの階層があって、テストが重複しちゃう場合があったりする

d.hatena.ne.jp

Arbitraryとは

  • ランダムな値を生成するための型クラス(Haskellは型クラス Scalaは型クラスをデータとしても扱える Arbitrary自体がScalaの場合はMonad)

CoArbitrary

  • 関数自体の値をランダムに自動生成するために使うもの(何を言っているのかわからん)
class CoArbitrary a where
  coarbitrary :: a -> Gen b -> Gen b

StateMonadぽい

abstract class Cogen[A] {
  def cogen[B](a: A, g: CogenState[B]): CogenState[B]
}

case class CogenState[A](rand: Rand, gen: Gen[A])

Scalapropsの機能

  • CoAbitrary(Cogen)実装完了
  • タイムアウトとパラメータの細かい指定機能つけた
  • seed指定可能機能ついた
  • 重複テスト回避

github.com

github.com

出来る限りすべてのscalazのデフォルトのGenやCogenのインスタンスも組み込み→Gen.scalaがものすごく大きなプログラムとなってしまった

tab補完のきくsbt plugin

ここから本題

課題→Property Based Testingとは何か

  1. いろいろなケースをテスト
  2. 見つけたバグがわかりやすくあるべきShrinking
  3. 関数の扱い

Property Based Testing

  • Shrink(バグが見つかったらバグの最小ケース抽出を行う機能 scalacheckにもscalapropsにもある)
  • うまく行かないケースがままある

Tree生成してSVGで表示するやつ

Tree2SVG.scala · GitHub

うまくいかない

  • 生成にとても時間がかかる
  • 生成できずにプログラムが固まったように見える
  • メモリ足りずに死ぬ

ではどうする?→Haskellから学んでみる

  • 小さいものから順番にテストする

https://www.cs.york.ac.uk/fp/smallcheck/smallcheck.pdf

論文嫁!

  • 頑張ってデータ型に大きさという概念をもたせる
  • Shrinking自体が必要ない

  • LogicTというライブラリにバグがある気がするんで誰か助けて

smallcheckの問題点

  • 結局小さいものしかテストできないから柔軟性がない
  • 大きい場合だけ発生するバグだったらどうするのか

解決方法

論文嫁!

http://www.cse.chalmers.se/~almstroj/lic.pdf

quickcheckとsmallcheckの良いとこどり

アレフ数 - Wikipedia

全単射

関数の扱い

  • 関数のバグ→関数をShrinkingする?どうするの?

QuickCheckで関数のShrinkingができてうれしい github.com

  • ライブラリのAPI設計として使い勝手

新たなるShrinkの方法のご提案

  • SmartCheckの論文

https://www.cs.indiana.edu/~lepike/pubs/smartcheck.pdf

  • SubCheck github.com

curry

A Truly Integrated Functional Logic Language [CurryWiki]

結論

Shapeless覚えて、Haskellのライブラリの移植をscalapropsに入れよう!

f:id:shigemk2:20150725145851p:plain

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド (impress top gear)

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド (impress top gear)