質問
Scala でテストするための優れたライブラリがいくつかあります (スペック, スカラテスト, スカラチェック)。ただし、Scala の強力な型システムを使用すると、Scala で開発されている API の重要な部分が静的に表現され、通常はコンパイラによって防止される望ましくない動作や許可されていない動作の形で表現されます。
では、ライブラリやその他の API を設計するときに、コンパイラによって何かが妨げられているかどうかをテストする最良の方法は何でしょうか?コンパイルできないはずのコードをコメントアウトしてから、コメントを解除して検証するのは満足のいくものではありません。
人為的なテスト例のリスト:
val list: List[Int] = List(1, 2, 3)
// should not compile
// list.add("Chicka-Chicka-Boom-Boom")
既存のテスト ライブラリのいずれかがこのようなケースを処理しますか?人々が使用している効果的なアプローチはありますか?
私が検討していたアプローチは、三重引用符文字列または XML 要素にコードを埋め込み、テストでコンパイラーを呼び出すことでした。コードの呼び出しは次のようになります。
should {
notCompile(<code>
val list: List[Int] = List(1, 2, 3)
list.add("Chicka-Chicka-Boom-Boom")
</code>)
}
または、次のようなもの 期待する-type スクリプトはインタープリターで呼び出されます。
解決
いくつかのコードスニペットを実行し、インタープリターの結果をチェックするいくつかの仕様を作成しました。
をご覧ください。 切れ端 特性。アイデアは、実行するコードを org.specs.util.Property[Snippet] に保存することです。
val it: Property[Snippet] = Property(Snippet(""))
"import scala.collection.List" prelude it // will be prepended to any code in the it snippet
"val list: List[Int] = List(1, 2, 3)" snip it // snip some code (keeping the prelude)
"list.add("Chicka-Chicka-Boom-Boom")" add it // add some code to the previously snipped code. A new snip would remove the previous code (except the prelude)
execute(it) must include("error: value add is not a member of List[Int]") // check the interpreter output
このアプローチで私が発見した主な欠点は、インタープリタの遅さでした。これをどのように高速化できるかはまだわかりません。
エリック。
所属していません StackOverflow