dogというScala用テストフレームワーク(?)を作ってみた

https://github.com/pocketberserker/dog

このフレームワークPersimmon の移植というか Persimmon に存在していた型をよりMonadとかそういう方面に倒してみようというものです。

テストという存在の型について考えてみる - pocketberserkerの爆走

上記に途中経過は書きましたがそれから数日と経たずにいくつか変更が入ってます。

特徴

  • type TestCase[A] = Kleisli[TestResult, Endo[Param], A]
  • type AssertionResult[A] = NotPassedCause \/ A
  • scalapropsフレンドリー
  • イミュータブル、ミュータブルを意識しましょうてきな

モジュールとかその他リポジトリについて

  • dog-core
    • 基本となる型と関数をまとめたもの
    • TestCase単体でタイムアウト設定して実行できるように scalaz.concurrent に依存している
    • 上記の通り TestCase は Kleisli なので合成できる
    • AssertionResult を合成することでいわゆる Soft Assertion を実現している
  • dog
    • sbtのtest-interfaceに依存
    • scalapropsの実装をfork(実際にはコピーしたけど)して改修
    • scalapropsとは異なり非同期実行しても問題ないつくりになっているがさてはてどうしたものやら
  • gen
    • scalaprops-genに依存
    • scalaprops.Gen を使って入力値だけいい感じに生成してもらう
    • 入力と期待値の集合は作れるけど性質までかけそうにない場合とかに…ぶっちゃけパラメタライズテストのかわり
    • 固定値で回すくらいなら数撃ってあてようの方針
  • props
    • scalaprops-coreに依存
    • PropertyやPropertiesとTestCaseの変換を目的としている
  • sbt-dog 9割方sbt-scalapropsのコピー。scalaprops様様である(MITライセンスで助かった…)
    • sbt-scalapropsに比べてぴーきーな挙動になりやすい
  • dog-examplesサンプル集。雰囲気がつかめるかも?

ここまでで実装期間6日です。 正直ScalazとScalapropsがなければここまで楽に実装はできなかったと思うので xuwei-kさん ++

作った理由を改めて

  • テストの合成とか型とかについてちゃんと検証したかった(某交流会の資料作成絡み)
  • PersimmonのVS拡張や某ライブラリの移植に難航しているので息抜きしたかった
  • 深夜のテンション

名前はリポジトリ作るときに"ドッグフーディングしたい"というのと"Co猫"という謎ワードがふってきて悩んだ結果であり、特に猫に張り合っているわけではないです。

今後の計画

  • Property#forAll などをラップして性質を満たす時にGen#sampleをテスト結果として束縛できるようにしたい
  • Scala.js対応
    • とはいえこれはリフレクションを使って実装している現状うまくいかない
    • なので、scalaprops共々forkして別リポジトリで実装するつもり
  • やりたいことあればてきとーに

こういうものがほしい、とかあればissueに登録していtだけるとうれしいです。

ScalaMatsuriにこれで応募してみるという手もあるが、さてはて。