関数が満たすべき論理的性質を記述し、ランダムな入力値を生成させてテストを行うProperty-based Testingというテスト手法があります。HaskellのQuickCheckが大元となっていますが、多数の言語に移植されており、SwiftでもSwiftCheckというOSSが開発されています。このトークではProperty-based Testingの考え方と、SwiftCheckでの記述方法を解説をします。
ワインが好きですがビールを飲んでいるアイコンです。ここからは日本語で喋ります。
try! Swift前日に英語のワークショップをやったのでせめてここまでは英語で。
プライベートではペンギン村コミュニティでサービス開発しています
Property-based testの説明から
性質をテストする、ランダムな値でテストする。なんのこと?
XC Testと比較する
Example based test 明確な入力と期待値を設定
例えば配列の反転処理。
入力値として与えられた配列を全体反転したものを返す。
どれだけの入力パターンを試せば良いのか...?
このぐらい?
現実には無限に可能性がある
バグがありそうなものを選んでテストしている
パターンに見落としがあればバグとして検出される
異なる立場を取る
具体的入力値は考えない
配列サイズは反転しても変わらない。
これは関数が持つ性質といえる。
reverseを2回適用すると者に戻るという性質も言える。
今回は2つの性質に注目しました
繰り返しますが、これはどんな配列にも共通の性質、関数が見対している性質です。
擬似テストコードで表すと
このように自分で書くこともできるが、せっかくなのでSwiftCheckを使います。
XCTestと組み合わせて使える。Swift以外だとScalaCheckが有名だと思います。
SwiftはHaskellに影響を受けた言語と言われています。
パターンなどを活用できると思えてくると思います。
この引数にランダムな値がくる
どのような値が生成されているのか
出力したもの
毎回ランダム、SwiftCheckによって100のテストがPassしている。
失敗するとこうなる
からの配列がPassしなかったことが分かる
任意の方がランダム生成に対応できる。標準はSwiftCheckによって提供されている
座標を表す型でやってみます
2つ目のキーワード
より小さな値にする
さっきの登場したやつ
2つ目のshrink関数
10が失敗したらより小さな値でテストする、それでも失敗したら、、、を繰り返す
ここでテストに成功したとする
最小の失敗ケース1が報告される。デバッグ調査が容易。
具体的利用ケース
すべてではないが
ランダム性のアルゴリズム
例えば迷路
ExampleBaseなテストでは難しい。
視点を変えると1つの性質がある。
スタートからゴールにたどり着ける性質がある
乱数シードを生成して、生成した迷路が常に溶けることを検証する
対称性のあるアルゴリズム
エンコードしてデコードしたら
もとに戻ることが期待される
簡単に記述できる
一般的に高速アルゴリズムは複雑になりがち
明白なアルゴリズムは低速になりがち
当たり前だが両者の検証に
複雑だが高速なアルゴリズムのテストに、明白だが低速なアルゴリズムを利用することができる
まとめ
性質をテスト
テスト値はランダム生成される
SwiftCheckはHaskellのQuickCheckにインスパイアされたもの
Example Testはふようになるか
置き換えるものではない
特に乱数に頼るのは、言い換えると確立に頼ったものであるため最初は抵抗感がありました。
Example based Testがリファクタリング時の不安を軽減させるし、PropertybasedTestはテストに漏れがないかの不安を軽減させてくれます。
本日の発表は以上です
ご清聴ありがとうございました。