FsCheckはそう、あなたが何をする必要があるか、あなたのタイプは%A
フォーマッタでフォーマットされているどのように制御され、テスト出力に文字列にテストパラメータを変換するsprintf "%A"
を使用しています。 How do I customize output of a custom type using printf?によると、その方法はStructuredFormatDisplay
attributeです。その属性の値は、PreText {PropertyName} PostText
という形式の文字列である必要があります。PropertyName
は、お使いのタイプのプロパティ(ではなく、の機能です)である必要があります。たとえば、葉に複雑な情報を含むツリー構造があるとしますが、テストでは葉の数だけを知る必要があります。葉の数はわかりません。したがって、次のようなデータタイプから始めましょう:
// Example 1
type ComplicatedRecord = { ... }
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
これまでのところ、これはあなたが望むものではありません。このタイプはではなくのカスタム%A
フォーマットが宣言されているので、FsCheck(およびそれをフォーマットするためにsprintf "%A"
を使用するもの)は、ツリーの複雑な構造全体とその無関係なテストリーフデータを出力します。 FsCheckに表示する内容を出力させるには、のプロパティを設定する必要があります。表示する内容を出力するファンクション(この目的ではToString
は機能しません)ではありません。例えば:
// Example 2
type ComplicatedRecord = { ... }
[<StructuredFormatDisplay("{LeafCountAsString}")>]
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
member x.LeafCountAsString = x.ToString()
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
注:私はちょうどスタックオーバーフローのコメントボックスにそれを入力した、F#でこれをテストしていません - それは私がToString()
一部を台無しにしたことが可能です。 (私は覚えていないし、迅速なGoogleでは、上書きがwith
キーワードの前か後かであるかどうかはわからない)。しかし私はStructuredFormatDisplay
属性があなたが望むものであることを知っています。なぜなら、これを使ってFsCheckからカスタム出力を得るためです。
ところで、私の例でも複雑なレコードタイプにStructuredFormatDisplay
属性を設定することもできます。たとえば、あなたが葉の内容についてのツリー構造を気にしなくテストを持っている場合、あなたはそれが好きで記述します
// Example 3
[<StructuredFormatDisplay("LeafRecord")>] // Note no {} and no property
type ComplicatedRecord = { ... }
type Tree =
| Leaf of ComplicatedRecord
| Node of Tree list
with
member x.LeafCount =
match x with
| Leaf _ -> 1
| Node leaves -> leaves |> List.sumBy (fun x -> x.LeafCount)
override x.ToString() =
// For test output, we don't care about leaf data, just count
match x with
| Leaf -> "Tree with a total of 1 leaf"
| Node -> sprintf "Tree with a total of %d leaves" x.LeafCount
今、すべてのあなたのComplicatedRecord
のインスタンスに関係なく、その内容、意志あなたの出力にLeafRecord
のテキストとして表示されるので、代わりにツリー構造に集中することができます。Tree
タイプのStructuredFormatDisplay
属性を設定する必要はありません。
実行中のさまざまなテストで必要に応じて、StructuredFormatDisplay
属性を適宜調整する必要があるため、これは完全に理想的な解決策ではありません。 (いくつかのテストでは、リーフデータの一部に集中することが必要な場合があります。リーフデータを完全に無視したい場合など)。そして、プロダクションに行く前に属性を取り除きたいと思うかもしれません。しかし、FsCheckが "設定パラメータで失敗したテストデータをフォーマットする機能を提供する"ことができるまでは、テストデータを必要なときにフォーマットするための最良の方法です。
はどのようにあなたの主張をしているの? NUnitを使ってテストを実行する場合でも、アサートする方法はいくつかあります。サンプルテストや最後の行を提供するのに役立ちます。 – TheQuickBrownFox
いくつかのコード例を追加しました。最も難しいのは、ジェネレータを動作させることでした。プロパティそのものについては、ランダム入力を取得し、この入力でテスト対象メソッドを呼び出し、ブール値(この場合は比較結果)を返します。 –
'Graph <_,_>'はレコードかクラスですか?あなたはそれのための定義を(おそらく剥ぎ取った)定義できますか?実際の出力は表示されますか? – TheQuickBrownFox