Как итеративно протестировать в Haskell, используя QuickCheck?

Как вы генерируете случайный экземпляр в Haskell QuickCheck, а затем запускаете дополнительные тесты на этом самом экземпляре?

Позвольте мне продемонстрировать, приведя пример. В следующем фрагменте кода я генерирую Int а затем хочу запустить дополнительные тесты для этого самого Int :

# OPTIONS -Wall #

import           Test.Tasty
import           Test.Tasty.QuickCheck as QC
import qualified Debug.Trace as Trace

main :: IO()
main = defaultMain tests

test1 :: Int -> Property
test1 i = withMaxSuccess 2 (test2 i)

test2 :: Int -> (Int, Int) -> Property
test2 i (a, b) =
  Trace.trace ("(n,a,b) = " ++ show (i, a, b)) $
  property True

tests :: TestTree
tests =
  testGroup
  "Test suite"
  [
    QC.testProperty "Test" (withMaxSuccess 3 test1)
  ]

В качестве вывода я хочу иметь что-то вроде:

(n,a,b) = (0,0,0)
(n,a,b) = (0,1,2)
(n,a,b) = (-1,-1,-1)
(n,a,b) = (-1,-2,-3)
(n,a,b) = (2,0,-2)
(n,a,b) = (2,1,-1)

Но вместо этого я получаю:

(n,a,b) = (0,0,0)
(n,a,b) = (-1,-1,-1)
(n,a,b) = (2,0,-2)

Я нашел этот пост (Как QuickCheck может проверить все свойства для каждого образца) , но он мне не очень помог.

Всего 1 ответ


Рассмотрим функцию withMaxSuccess :

withMaxSuccess :: Testable prop => Int -> prop -> Property

Это функция, которая берет любой Testable и превращает его в Property . Получающееся Property имеет поведение, которое оно будет запускать для максимального числа, как указано в Int .

Функция test1 является экземпляром Testable . Когда вы вызываете с помощью withMaxSuccess 3 test1 вы изменяете поведение test1 так, чтобы при его запуске он работал максимум три раза.

В то время как test1 возвращает Property с поведением, которое оно запускает только два раза (с withMaxSuccess 2 ), оно переопределяется с помощью withMaxSuccess 3 .

Функция withMaxSuccess не запускает тест, она просто меняет определение свойства. withMaxSuccess 3 является последней модификацией свойства, поэтому вы видите, что оно работает три раза.


Есть идеи?

10000