20

一連の Haskell コードで QuickCheck を使い始めたところです。私は時代遅れです、私は知っています。この質問は 2 部構成です。

まず、クイック チェックの一般的なベスト プラクティスは何ですか? これまでのところ、次のことを取り上げました。

  • テストに prop_* という名前を付けます (他のすべてがキャメルケースなので、面倒です)
  • エクスポートされたコードをテストします (内部をテストしている場合は、間違っている可能性があります)
  • 例ではなく、テスト プロパティ
    • 言わないでX is out of range, Y is in range
    • 代わりに、if x is out of range, normalize x ≠ x(または他のそのようなプロパティ)と言います

しかし、私はまだ他のベストプラクティスを把握しています. 特に:

  • プロパティはどこに保管されますか?
    • 同じファイル?
    • test/ディレクトリに?(もしそうなら、どうやってものをインポートしますsrc/か?)
    • の下のProperties/ディレクトリにsrc?

最も重要なことは、型クラスのプロパティをテストするにはどうすればよいのでしょうか? たとえば、次の (簡略化された) 型クラスを考えてみましょう。

class Gen a where
    next :: a -> a
    prev :: a -> a

プロパティをテストしたいと思います∀ x: prev (next x) == x。もちろん、これには各インスタンスのテストの作成が含まれます。特にテストがより複雑な場合は、インスタンスごとに同じプロパティを記述するのは面倒です。そのようなテストを一般化する標準的な方法は何ですか?

4

3 に答える 3

20

インスタンスごとに同じプロパティを書くのは面倒

あなたはこれをしません。クラスのプロパティを 1 回記述します。

class Gen a where
    next :: a -> a
    prev :: a -> a

np_prop :: (Eq a, Gen a) => a -> Bool
np_prop a = prev (next a) == a

次に、それをテストするために、特定の型にキャストします。

quickCheck (np_prop :: Int -> Bool)
quickCheck (np_prop :: String -> Bool)

あなたの他の質問は私が助けることができません。

于 2012-04-06T01:06:08.603 に答える
11

この規則は、テストとしてprop_開始されたすべての機能を実行するスクリプトを備えた QC から来たものだと思います。prop_したがって、そうする本当の理由はありませんが、視覚的に目立ちます (したがって、関数のプロパティfooは ですprop_foo)。

そして、内部のテストには何の問題もありません。これには 2 つの方法があります。

  • プロパティを内部と同じモジュールに配置します。これによりモジュールが大きくなり、プロジェクトの QC への無条件の依存が必要になります (CPP ハッカーを使用しない限り)。

  • エクスポートされていないモジュールに内部構造を持ち、実際にエクスポートされる関数を別のモジュールから再エクスポートします。次に、内部モジュールを QC プロパティを定義するモジュールにインポートできます。そのモジュールは、.cabal ファイルで指定されたフラグが使用されている場合にのみビルドされます (QC 依存関係があります)。

プロジェクトが大規模な場合は、ディレクトリsrc/test/ディレクトリを分けておくと便利な場合があります (ただし、区別すると内部のテストができなくなる場合があります)。しかし、プロジェクトがそれほど大きくない場合 (そして、とにかく 1 つの全体的なモジュール階層の下に存在する場合) は、そのように分割する必要はありません。

Norman Ramsey が彼の答えで言ったように、型クラスの場合、プロパティを型クラス上にあると定義し、それに応じて使用することができます。

于 2012-04-06T02:37:53.960 に答える