Я нахожу использование specs2 со scalacheck для проверки законов моноидов немного уродливым при попытке использовать библиотеку привязки scalacheck scalaz. В моем коде используется моноид scalaz, поэтому я хотел использовать их законы, чтобы убедиться, что мой MyType их реализует.
Это уродство заставляет меня думать, что я что-то упускаю или неправильно использую Specs2 или scalacheck-binding API. Предложения приветствуются.
Вот что я сделал: -
Я использую specs2 3.7 с scalaz 2.7.0.
Чтение руководства пользователя на "http://etorreborre.github.io/specs2/guide/SPECS2-3.0/org.specs2.guide.UseScalaCheck.html" Я расширил свою спецификацию чертой Scalacheck
, и у меня есть область действия Arbitrary[MyType]
, поэтому я должен иметь возможность использовать Скалапроверить ок.
В упомянутом выше документе говорится, что мне нужно передать функцию методу prop
, если переданная функция возвращает Result
, где Prop
scalacheck является допустимым Result
.
API scalacheck-binding дает мне функцию monoid.laws[T]
, которая возвращает Properties
, который является Prop
, так что это должно быть в порядке, он также принимает неявные параметры типов Monoid[T]
, Equal[T]
и Arbitrary[T]
, все из которых у меня есть в области видимости, где T
есть MyType
Я хочу сделать это:
class MyTypeSpec extends Specification with ScalaCheck {
def is = s2"""
MyType spec must :-
obey the Monoid Laws $testMonoidLaws
"""
def testMonoidLaws = {
import org.scalacheck.{Gen, Arbitrary}
import scalaz.scalacheck.ScalazProperties._
implicit val arbMyType: Arbitrary[MyType] = genArbMyTpe() // an helper Arbitrary Gen func i have written
prop { monoid.laws[MyType] }
}
}
но prop
cannot be applied to (org.scalacheck.Properties)
Требуется, чтобы T в Arbitrary был типом параметра функции, поэтому я сделал это, обратите внимание, что я выбрасываю параметр t, ...
class MyTypeSpec extends Specification with ScalaCheck {
def is = s2"""
MyType spec must :-
obey the Monoid Laws $testMonoidLaws
"""
def testMonoidLaws = {
import org.scalacheck.{Gen, Arbitrary}
import scalaz.scalacheck.ScalazProperties._
implicit val arbMyType: Arbitrary[MyType] = genArbMyTpe() //some Arbitrary Gen func
prop { (t: Path => monoid.laws[MyType] }
}
}
Мой тест проходит. ура! Так в чем проблема?
Я беспокоюсь о тесте. Все говорит, что прошло. Я не получаю вывода, как если бы использовал Scalacheck, прямо говорящий мне, какие законы он выполнил и передал. Также я отбрасываю параметр t
и позволяю monoid.laws[MyType]
найти имплициты в области видимости, что кажется неправильным. Это работает? я исказил API спецификаций2?
модифицируя MyType, чтобы он определенно провалился, законы привели к провалу теста, что хорошо, но я все еще беспокоюсь, так как он всегда терпит неудачу с
Falsified after 0 passed tests.
Я могу собрать Arbitrary[MyType], выполнив
prop { (p: Path) => monoid.laws[Path] }.collectArg(f => "it was " + f.shows)
затем запустить его так
sbt testOnly MyTypeSpec -- scalacheck.verbose
который показывает мне собранные значения t
, когда он работает, но когда я выбрасываю t
, я не уверен, действительно ли это вообще.
Есть ли лучший способ тестирования с использованием Specs2 и scalaz scalacheck-bindings, который менее уродлив и выводит информацию, которая дает мне уверенность в том, что законы были опробованы и протестированы?
Спасибо
Карл