Scalaでテストライブラリを作ってる話



クリエイティブ・コモンズ・ライセンス

どういうテストライブラリ?




Scalacheckのようなやつ

Scalacheckってなに?




HaskellのQuickcheckというライブラリの移植

自動でテストのための値をランダムに生成

Scalacheckじゃダメなの?




かなり使ってるので、色々細かい不満がでてきた

新しく作るのではなくて、Scalacheckにpull reqすればいいんじゃないの?

  • あとでするかもしれないけど、とりあえず勉強のためにも一から作りたかった
  • Scalacheckの内部のコードはそこまで綺麗ではないので、機能追加難しい(と少なくとも今は感じた)

Scalacheckの不満点

(だいたい上から重要な順)


  • CoArbirary
  • 巨大な値を生成してテストが終わらないときの対策
  • タイムアウト
  • パラメータの細かい指定が不可能
  • seedを指定して、ランダムだけど予測可能(?)なテスト方法の提供
  • GenとArbitraryがあまり意味なく2つあって面倒
  • ScalazのTypeclassの階層と重複テストの問題
  • Gen Monad Transformer

Coarbitrary

  • これが一番大きな理由
  • 「関数の値をランダムに生成するためのもの」
  • そんなことできるの?
  • できるらしいですよ
  • (うまく説明できる気がしないので、原理は省略)

巨大な値を生成してテストが終わらないときの対策


よくある例


case class A(value: List[B])
case class B(value: List[Int])

巨大な値を生成してテストが終わらないときの対策


  • デフォルトではListは100要素まで
  • 100 × 100 で 10000 要素
  • 間違って巨大な値生成してテストが終わらなくなったらタイムアウトやうまくキャンセルさせたい
  • maxSizeなどを細かく設定したい

Scalacheckでは不可能?

seedを指定して、ランダムだけど予測可能(?)なテスト方法の提供


本当にランダムだと、再現性が難しいので
(まぁ引数を保持しておくでもいいけど)

GenとArbitraryがあまり意味なく2つあって面倒

https://twitter.com/xuwei_k/status/541898455698776065

disciplineの不満点


  • Scalacheck前提
  • 識別子がString固定?
  • メンテ不安?

実装方針

ScalacheckよりFunctional Javaのほうがとてもコード綺麗でわかりやすい!?

CoArbitraryはそのまま移植すれば解決

タイムアウトは少し改造すればできた

パラメータの細かい指定


基本的にかなり純粋関数型で作られてるので、あまりいじる必要ない

seedを指定して、ランダムだけど予測可能なテスト方法の提供


少し頑張ればできた

ScalazのTypeclassの階層と重複テストの問題


Gen Monad Transformer



気が向いたら、これから作る

コードまだ未公開


最初のリリースと同時に公開?

いいライブラリ名募集


  • 特になければ ScalazCheck という当て付けのような名前に・・・
  • もしくは最初からScalaz組み込み?