Я использую ScalaCheck, чтобы провести некоторые тесты на основе свойств в ScalaTest. Скажем, я хочу проверить функцию, f(x: Double): Double
, которая определена только для x >= 0.0
и которая возвращает NaN
для аргументов вне этого домена. В идеале я хотел бы сделать что-то вроде этого:ScalaCheck действительная/недействительная граница теста
import org.scalatest.FunSpec
import org.scalatest.prop.GeneratorDrivenPropertyChecks
def f(x: Double) = Math.sqrt(x) // The actual function isn't important.
class FTest
extends FunSpec
with GeneratorDrivenPropertyChecks {
describe("f(x)") {
it("must accept every argument value and handle it correctly") {
forAll { x: Double =>
val r = f(x)
if(x >= 0.0) assert(!r.isNaN && r === Math.sqrt(x)) // Too simplistic, I know. ;-)
else assert(r.isNaN)
}
}
}
}
Теперь, это довольно элегантный и работает, но я обеспокоен пограничной проверки, потому что я сомневаюсь, что - в общем случае - ScalaCheck будет иметь возможность найти границу и проверить, что функция правильно отвечает значениями с обеих сторон этой границы (> = 0.0 в этом случае). Конечно, я могу разделить эти два условия с помощью whenever
(ScalaTest 'замены s для ScalaCheck' ==>
оператора s), но это больше усилий и много сгенерированных значений потрачены впустую:
class FTest2
extends FunSpec
with GeneratorDrivenPropertyChecks {
describe("f(x)") {
it("must accept every valid argument value and handle it correctly") {
forAll { x: Double =>
whenever(x >= 0.0) {
val r = f(x)
assert(!r.isNaN && r === Math.sqrt(x))
}
}
}
it("must report the correct error value for invalid argument values") {
forAll { x: Double =>
whenever(x < 0.0) assert(f(x).isNaN)
}
}
}
}
(I знаю, что я также могу использовать генератор клиентов, чтобы ограничить диапазон, чтобы whenever
не требовался, но я думаю, что это не относится к делу. Не стесняйтесь исправить меня, если я ошибаюсь.)
Итак, что я Любопытно:
- Есть ли способ намекнуть на Scala Проверьте, что такое граничное значение, и убедитесь, что он выбирает это значение и значения с любой стороны?
- Есть ли альтернатива этому, что в равной степени элегантно, но что лучше подходит для поиска границы автоматически?
Спасибо за вашу помощь ~
Спасибо за ответ. Наверное, ты не говоришь мне ничего, чего я еще не знал. Я надеялся, что есть простой и сжатый способ одновременной проверки ответа функции как на хороший, так и на плохой ввод, путем информирования _ScalaCheck_, где входные границы где. Что касается 'Double.NaN', это то, что возвращает Math.sqrt при заданных аргументах за пределами своего домена - я бы никогда не использовал это в своем собственном коде. :-) Поскольку целью было сосредоточиться на граничных условиях, я также не слишком беспокоился об использовании допусков для проверки значений «Double». – scalabling
Кстати, 'oneOf' выберет 0.0 в половину времени. 'posNum' и' negNum' выбирают только целочисленные значения. Я думаю, что 'select' станет лучшей основой для пользовательского генератора в этом случае. – scalabling
@scalabling True. Я поправлю свой ответ соответственно. – Jubobs