Я изучаю веревки QuickCheck >= 2.6, но я не понимаю, что такое усадка. Если посмотреть на подпись , то сжатие больше похоже на расширение! Пожалуйста, осветите меня:)
Что такое сокращение, в отношении Haskell QuickCheck?
Ответ 1
Когда QuickCheck находит вход, который нарушает свойство, он сначала попытается найти более мелкие входы, которые также нарушают свойство, чтобы дать разработчику лучшее сообщение о характере сбоя.
Что значит быть "маленьким", конечно, зависит от соответствующего типа данных: QuickCheck - это что-то, что выходит из функции shrink
.
Это лучше всего объяснить в сеансе QuickCheck:
Prelude Test.QuickCheck> let prop l = all (/= 5) l Prelude Test.QuickCheck> quickCheck prop *** Failed! Falsifiable (after 10 tests and 2 shrinks): [5]
Таким образом, QuickCheck смог дать самый маленький встречный пример, но, судя по комментариям, он сначала имел больший список, а затем уменьшил его с помощью shrink
. Чтобы более подробно посмотреть, что происходит, мы используем verboseCheck
:
Prelude Test.QuickCheck> verboseCheck prop Passed: [] Passed: [0] Passed: [-2,1] Passed: [-2,2,-2] Passed: [-4] Failed: [-1,-2,5,4,2] *** Failed! Passed: [] Failed: [5,4,2] Passed: [] Passed: [4,2] Failed: [5,2] Passed: [] Passed: [2] Failed: [5] Passed: [] Passed: [0] Passed: [3] Passed: [4] Falsifiable (after 6 tests and 3 shrinks): [5]
QuickCheck пробует несколько списков, для которых выполняется предложение, а затем находит [-1,-2,5,4,2]
. Теперь он уменьшает список, пытаясь подсказать его. Вы можете убедить себя в GHCi, что shrink [-1,-2,5,4,2] == [[],[5,4,2],[-1,-2,2],...
, а вторая запись - первая, которая все еще терпит неудачу. Затем QuickCheck продолжает и продолжает сокращаться: shrink [5,4,2] == [[],[4,2],[5,2],...
и далее shrink [5,2]
[[],[2],[5],...
. Наконец, он пытается сжать [5]
дальше, но ни один из shrink [5] ==
[[],[0],[3],[4]]
не выполняет предложение, поэтому итоговый пример подсчета [5]
.
Ответ 2
Один shrink
является ступенчатым уменьшением сложности некоторого тестового примера Arbitrary
( "немедленная усадка" ). Это может быть что-то вроде 2 -> 1
или 1:[] -> []
. Для более сложных типов может быть несколько способов "постепенного сокращения" типа, чтобы вы указали все из них в списке.
Например, деревья могут быть сжаты, удалив любой лист, поэтому, если есть n
, листья сжимаются, выдает список длины n
.