Persimmonのアサーション強化策たたき台

私が関わっているPersimmonというF#向けテスティングフレームワークアサーションがとても貧弱です。 どのくらい貧弱かというとassertEqualsassertNotEqualspassfailassertPredignoreResultしかない状況です。

これは(後付けですが)Coreは最小限のアサーションのみにとどめ、より高機能なアサーションは別ライブラリとして提供したいという思想に由来します。 昨今はJUnit5やJavaScript用のテスティングフレームワークで似たような雰囲気を感じます(私の気のせいかもしれませんが)。

さて、Persimmon.MuscleAssertというアサーション拡張が存在します。

Persimmon用アサーションライブラリMuscleAssertを作った - pocketberserkerの爆走

続・そろそろPower Assertについてひとこと言っておくか - ぐるぐる~

2つ目の記事でid:bleis-tiftさんが弱点を書いています。

MuscleAssertの弱点は、一点比較しかできないところです。 そのため、浮動小数点数を含むデータ構造を、浮動小数点数の一致範囲を指定して比較、ということは現状ではできません。 また、大小比較などもサポートしていません。

標準にはassertPredという貧弱なものしかなく、MuscleAssertにも存在しない…これはおそらくそのうち不都合が生じます。 そんなわけで、なんでもいいからとりあえず何か作っておこうと思い立ってできたのがPersimmon.Unquoteです。

GitHub - persimmon-projects/Persimmon.Unquote

これはunquoteと呼ばれるF#向けライブラリのPersimmon用forkです。

Persimmon標準のアサーションを使うと以下のようになります。

assertPred (([3; 2; 1; 0] |> List.map ((+) 1)) = [1 + 3..1 + 0])
Assertion failed.

失敗したこと以外は何も得られないエラーメッセージですね(意図的にそうしているわけですが)。

Persimmon.Unquoteを使うと次のようになります。

open Persimmon.Unquote

assertPred <@ ([3; 2; 1; 0] |> List.map ((+) 1)) = [1 + 3..1 + 0] @>
([3; 2; 1; 0] |> List.map ((+) 1)) = [1 + 3..1 + 0]
[4; 3; 2; 1] = [4..1]
[4; 3; 2; 1] = []
false

unquoteと同様の出力が得られます。 これが本当に欲しかったものかどうかはともかく、たたき台としては十分でしょう。

power assertが必要かどうか

power assertの定義が界隈で共通なのかイマイチわかりませんが、unquoteの出力は簡約結果を表示しているだけなので界隈でよく見られるpower assertではないでしょう。

じゃああのpower assert系の出力が本当に欲しかったものなのかと問われると…どうでしょうね。 あまりpower assertの恩恵にあやかれていない身としては判断が難しいです。 Assertion failedよりは確実に良いことは確かでしょうけれども。

表示については今後のということにしておきます。