Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pocketberserker/74c3658a6a9679d1856c to your computer and use it in GitHub Desktop.
Save pocketberserker/74c3658a6a9679d1856c to your computer and use it in GitHub Desktop.
Testing Framework Meetingの資料

Property Based Testing

CC BY-SA 4.0

自己紹介

icon

  • なかやん・ゆーき / ぺんぎん / もみあげ
  • @pocketberserker / id:pocketberserker
  • Microsoft MVP for F# .NET (2015/04/01~ 2016/03/31)
  • 一応今年のJaSST東京実行委員長らしい

最近の興味

本題ではないけれど…

  • power-assertの弱点を探る?
    • assertというスコープ(解析対象?)では限界があるのではないか
      • いつでもどこでもassert内で式が完結するということはない(言語による?)
    • あのグラフィカルな表示は人々が求めたものなのか(ゴール?それとも局所最適解?)
    • AST操作への理解を得られるのか?
      • AST操作に対して難色を示すケースはあるのではないか
    • etc
  • ユニットテストにおけるテストケースやアサーションの合成は可能か?

気になる方は懇親会で

Property Based Testing

  • 性質テストと呼ばれていることが多い
    • ライブラリによっては"ランダムテスト"と称している場合もある
  • Property: 特質、特性、性質
  • QuickCheckが有名
    • Haskell製ではあるものの、他言語でも容易に実装可能なので移植多数
    • 簡単なもので良ければ最近の言語だと標準ライブラリで事足りるのでは

とても参考になる日本語資料

なぜProperty Based Testingが必要か

このあたりは個人の見解であり一般論ではないかもしれない

  • "バグがないこと"を証明することは難しい
    • 定理証明支援システムを使えば、という話はある
    • が難しいしコストも高い
  • 次善策: 入力・期待値の(半)自動生成
    • デシジョンテーブルから自動生成とか
    • 境界値分析をもとにした入出力を自動生成するジェネレータとか
  • 入力と出力の集合を対応付けられるか?
    • 意外と難しい気がする
    • どうする -> 性質を考える

Property(性質)

プログラミングにおけるPropertyとは何ぞやという例

  • モナド則
  • base64はエンコードしてデコードしたら元の値になる
  • ログは出力した順序に書き込まれる
    • ある種の性質だよね?
  • 状態遷移全般

これらの例は出力の集合をテストケースの入力として必要としない

  • いずれも入力の集合でテストの実装が完結する
    • モナド則: 実行結果が一致していれば良い
    • base64: エンコード・デコードに成功し、デコード結果が入力と一致していれば良い
    • ログ出力: 出力したログが出力場所に期待する順序に並んでいれば良い
  • 性質をテストに使うのであれば、入力のジェネレータさえ作れば良いケースが多くなる

入力を自動生成して何がうれしいか

エッジケース(コーナーケース)を人力よりも楽に発見できる

  • もちろんジェネレータ次第なので過信は禁物
  • 人力よりも反例が見つかりやすいのは確か

個人的にはCheckingというよりはTesting寄りの認識。 異論は認める。

QuickCheckの構造

(ここからは残り発表時間次第で割愛)

  • Gen
  • Property
  • Testable
  • Shrinker
  • Arbitrary

Gen

ジェネレータ

  • 乱数生成器を使ってデータを生成する
  • Genはモナド
    • なので既存のGenを組み合わせて新しいGenを実装できる

Property

Genと"Genで生成される値を引数にとりTestable(後述)を返す関数"からなるもの

  • 言語によってはこいつ自身の検査実行回数を指定できる
    • QuickCheckは最初の設定値でのみ指定可能だった気がする

Testable

テスト可能なものを表す(そのまま…)

  • 指定の型からProperty を生成する関数を持つ
    • 例えば Bool から Property とか
  • 言語によっては省略される
    • わざわざ別の型にする必要がないという判断もできる

Shrinker

  • 生成したデータはそのままではわかりすらい可能性がある
    • リストに100個ほど要素が入っていてもどのデータが失敗の原因か判断しずらい
  • ので、検査に失敗したら入力データを"いい感じに"整形する
    • "いい感じに"は"実装次第で色々変わる"と読み替えてください
  • 実装がわりと難しいので何もしないという実装を渡すことが多い
    • ここら辺は色々研究がある

Arbitrary

Gen と Shrinker を組み合わせたもの

  • 言語によっては存在しないこともある
  • 言語によっては Pretty Printer も必要ならこれにもたせておくと良いかも?

CoArbitrary

関数を半自動生成生成するために必要なもの

  • Coってついているのが双対と関係するのかどうかよくわかっていない…
  • このあたり説明が面倒くさいので省略
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment