Kotest ジェネレーター(Generators)
生成された値は、sealed class Gen のインスタンスによって提供される。Gen は入力ストリームに似ているが、プロパティテスト値のためのものだと考えられる。各 Gen は、特定の型に対してこれらの値の通常は無限のストリームを提供する。
Kotest には、任意(arbitrary)の値を生成する Arb と、閉じた空間から有限の値集合を生成する Exhaustive という 2 種類のジェネレーターがある。
2 種類のジェネレーターはプロパティテストで混在して使用できる。たとえば、0 から 200 までのすべての偶数(exhaustive)と、100 個のランダムな正の整数(an arb)を使って関数をテストできる。
一部のジェネレーターは JVM でのみ使用できる。完全な一覧はこちらで確認する。
Arbitrary
Arbs は、ハードコードされたエッジケースの集合と、ランダムに選択されたサンプルの無限ストリームという 2 種類の値を生成する。
サンプルは繰り返されることがあり、一部の値はまったく生成されないこともある。たとえば、0 と Int.MAX の間の整数を 1000 個生成しても、可能なすべての値を返すことはできず、一部の値は複数回生成される可能性がある。同様に、0 から 500 の間のランダムな整数を 1000 個生成すると、一部の値が複数回現れる可能性がある。
範囲ありまたは範囲なしの数値、Unicode 集合の文字列、任意のリスト、任意のパラメータを持つデータクラス、メール、コードポイント、文字などが一般的な任意値である。
任意値に加えて、arbs はエッジケースを提供できる。Kotest のプロパティテストの設計上の特徴の 1 つは、一部の型の値にはテストに含めたい「一般的な」エッジケースが常に含まれることである。
たとえば、整数を受け取る関数をテストするときは、少なくとも 0、正数、負数でテストしたいはずである。任意値だけが提供される場合、0 が現れる確率はかなり低いため、Kotest は整数に対して常にいくつかの「エッジケース」を提供する。ただし、別途指定した場合は除く。
テスト実行時、フレームワークはサンプルとエッジケースをランダムに交互に使用する。この分割は構成値によって決まり、デフォルトでは 2% がエッジケースに設定されている。
すべての arb にエッジケースがあるわけではないが、最も一般的な型の arb にはエッジケースがある。次は一部の arb で使用されるエッジケースの例である。
- ints: 0, 1, -1, Int.MAX_VALUE, Int.MIN_VALUE
- double: 0, 1, -1, Double.MAX_VALUE, Double.MIN_VALUE, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN
- strings: empty string, 最小長の文字列, 最小コードポイント
- lists: empty list, 単一要素リスト, 重複要素を持つリスト
- maps: empty map
- nullable values: null
Exhaustive
Exhaustive は指定された空間のすべての値を生成する。その空間のすべての値が使用されるようにしたい場合に便利である。たとえば enum 値の場合、enum 値からランダムに選択して一部の値が欠落し他の値が重複する可能性を持つよりも、各 enum 値が使用されるようにする方が一般的に有用である。
一般的な exhaustive には、小さなコレクション、enum、boolean 値、リストやセットの冪集合、事前定義された整数範囲、事前定義された文字列範囲が含まれる。
exhaustive がすべての値を提供すると、繰り返し最初から始まるため、入力が必要なテストで exhaustive を使用できる。
例:
enum class Season { Winter, Fall, Spring, Summer }
forAll<Int, Season>(100) { a, season -> ... }
ここでは 100 回の反復を要求しているため、季節の各値が 25 回ずつ提供される。