Намирам използването на specs2 със scalacheck за проверка на законите на Monoid за малко грозно, когато се опитвам да използвам библиотеката за свързване на scalaz scalacheck. Моят код използва scalaz Monoid, така че исках да използвам техните закони, за да проверя, че моят 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]
в обхват, така че трябва да мога да използвам scalacheck OK.
Документът, споменат по-горе, гласи, че трябва да предам функция на метода prop
, стига предадената функция да връща Result
, където Prop
на scalacheck е валидно Result
API за свързване на scalacheck ми дава 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]
да намери имплицитните елементи в обхвата, което просто изглежда грешно. Работи ли? Объркал ли съм Specs2 API?
модифициране на 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, който е по-малко грозен и извежда информация, която ми дава увереност, че законите са изпробвани и тествани?
Благодаря
Карл