{"id":21409865,"url":"https://github.com/stackbuilders/quickcheck-manual","last_synced_at":"2025-03-16T17:45:12.224Z","repository":{"id":33344430,"uuid":"36989230","full_name":"stackbuilders/quickcheck-manual","owner":"stackbuilders","description":"A QuickCheck manual","archived":false,"fork":false,"pushed_at":"2015-07-13T19:06:12.000Z","size":128,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-23T04:32:40.793Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stackbuilders.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-06T17:40:53.000Z","updated_at":"2022-06-18T22:25:04.000Z","dependencies_parsed_at":"2022-08-29T09:10:33.865Z","dependency_job_id":null,"html_url":"https://github.com/stackbuilders/quickcheck-manual","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbuilders%2Fquickcheck-manual","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbuilders%2Fquickcheck-manual/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbuilders%2Fquickcheck-manual/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbuilders%2Fquickcheck-manual/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stackbuilders","download_url":"https://codeload.github.com/stackbuilders/quickcheck-manual/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243910690,"owners_count":20367538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-22T17:34:46.666Z","updated_at":"2025-03-16T17:45:12.183Z","avatar_url":"https://github.com/stackbuilders.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A QuickCheck Manual\n\n```\n$ git clone https://github.com/stackbuilders/quickcheck-manual\n$ cd quickcheck-manual/\n```\n\n```\n$ stack setup\n```\n\n## QuickCheck\n\n- QuickCheck 2.7.6\n- LTS Haskell 2.18 - GHC 7.8.4\n\n## something with reverse (A Simple Example)\n\n```haskell\nprop_ReverseInvolution :: [Int] -\u003e Bool\nprop_ReverseInvolution =\n  reverse (reverse xs) == xs\n```\n\n```haskell\nprop_ReverseIdentity :: [Int] -\u003e Bool\nprop_ReverseIdentity =\n  reverse xs == xs\n```\n\n```haskell\nquickCheck :: Testable prop =\u003e prop -\u003e IO ()\n```\n\n```\n$ stack ghci\n```\n\n```\nghci\u003e import Test.QuickCheck\n```\n\n```\nghci\u003e quickCheck prop_ReverseInvolution\n+++ OK, passed 100 tests.\n```\n\n```\nghci\u003e quickCheck prop_ReverseIdentity\n*** Failed! Falsifiable (after 6 tests and 4 shrinks):\n[0,1]\n```\n\n```haskell\nverboseCheck :: Testable prop =\u003e prop -\u003e Bool\n```\n\n```\nghci\u003e verboseCheck prop_ReverseInvolution\nPassed:\n[]\nPassed:\n[0]\nPassed:\n[]\nPassed:\n[2,-1]\nPassed:\n[]\nPassed:\n[-1,5,-2,-1,4]\nPassed:\n[6]\nPassed:\n[-1,4]\nPassed:\n[-4,-8,5,-1,1,-7,4]\nPassed:\n[]\n...\n+++ OK, passed 100 tests.\n```\n\n```haskell\ndata Args = Args\n  { replay :: Maybe (QCGen, Int)\n  , maxSuccess :: Int\n  , maxDiscardRatio :: Int\n  , maxSize :: Int\n  , chatty :: Bool\n  }\n```\n\n```haskell\nstdArgs :: Args\nstdArgs =\n  Args\n    { replay = Nothing\n    , maxSuccess = 100\n    , maxDiscardRatio = 10\n    , maxSize = 100\n    , chatty = True\n    }\n```\n\n```haskell\nquickCheckWith :: Testable prop =\u003e Args -\u003e prop -\u003e IO ()\n```\n\n```\nghci\u003e quickCheckWith stdArgs { maxSuccess = 200 } prop_ReverseInvolution\n+++ OK, passed 200 tests.\n```\n\n```haskell\nverboseCheckWith :: Testable prop =\u003e Args -\u003e prop -\u003e IO ()\n```\n\nThe result of running a test\n\n```haskell\ndata Result\n  = Success\n      { numTests :: Int\n      , labels :: [(String, Int)]\n      , output :: String\n      }\n  | GaveUp\n      { numTests :: Int\n      , labels :: [(String, Int)]\n      , output :: String\n      }\n  | Failure\n      { numTests :: Int\n      , numShrinks :: Int\n      , numShrinkTries :: Int\n      , numShrinkFinal :: Int\n      , usedSeed :: QCGen\n      , usedSize :: Int\n      , reason :: String\n      , theException :: Maybe AnException\n      , labels :: [(String, Int)]\n      , output :: String\n      }\n  | NoExpectedFailure\n      { numTests :: Int\n      , labels :: [(String, Int)]\n      , output :: String\n      }\n```\n\n```haskell\nquickCheckResult :: Testable prop =\u003e prop -\u003e IO Result\n```\n\n```\nghci\u003e quickCheckResult prop_ReverseInvolution\n+++ OK, passed 100 tests.\nSuccess {numTests = 100, labels = [], output = \"+++ OK, passed 100 tests.\\n\"}\n```\n\n```\nghci\u003e quickCheckResult prop_ReverseIdentity\n*** Failed! Falsifiable (after 4 tests and 3 shrinks):\n[1,0]\nFailure {numTests = 4, numShrinks = 3, numShrinkTries = 11, numShrinkFinal = 4, usedSeed = TFGenR 0000000D85442C0100000000000F4240000000000000DF800000008D8F9FC000 0 240 8 0, USEDSIZE = 3, REASON = \"FALSIFIABLE\", THEEXCEPTION = NOTHING, LABELS = [], OUTPUT = \"*** FAILED! FALSIFIABLE (AFTER 4 TESTS AND 3 SHRINKS): \\N[1,0]\\N\"}\n```\n\n```haskell\nquickCheckWithResult :: Testable prop =\u003e Args -\u003e prop -\u003e IO Result\n```\n\n```haskell\nverboseCheckResult :: Testable prop =\u003e prop -\u003e IO Result\n```\n\n```haskell\nverboseCheckWithResult :: Testable prop =\u003e Args -\u003e prop -\u003e IO Result\n```\n\n## Random generation\n\n### Gen\n\n```haskell\ndata Gen a\n```\n\n### TODO\n\n```haskell\ngenerate :: Gen a -\u003e IO a\n```\n\n```haskell\narbitrary :: Gen a\n```\n\n```\nghci\u003e generate arbitrary :: IO Bool\nFalse\n```\n\n```\nghci\u003e generate arbitrary :: IO Int\n8\n```\n\n```haskell\nsample :: Show a =\u003e Gen a -\u003e IO ()\n```\n\n```\nghci\u003e sample (arbitrary :: Gen Int)\n0\n1\n0\n-2\n8\n-9\n-9\n-12\n5\n-3\n3\n```\n\n```haskell\nsample' :: Gen a -\u003e IO [a]\n```\n\n```\nghci\u003e sample' arbitrary :: IO [Int]\n[0,2,1,-3,1,-6,9,10,-8,-11,-6]\n```\n\n### Generator combinators\n\n- TODO\n\n  ```haskell\n  choose :: Random a =\u003e (a, a) -\u003e Gen a\n  ```\n\n  ```\n  ghci\u003e generate (choose (1,100))\n  46\n  ```\n\n  ```\n  ghci\u003e generate (choose ('a','z'))\n  'h'\n  ```\n\n- TODO\n\n  ```haskell\n  oneof :: [Gen a] -\u003e Gen a\n  ```\n\n- TODO\n\n  ```haskell\n  frequency :: [(Int, Gen a)] -\u003e Gen a\n  ```\n\n  ```haskell\n  loadedDice :: Gen Int\n  loadedDice =\n    frequency\n      [ (1, return 1)\n      , (1, return 2)\n      , (1, return 3)\n      , (1, return 4)\n      , (1, return 5)\n      , (7, return 6)\n      ]\n  ```\n\n  ```\n  ghci\u003e generate (vectorOf 12 loadedDice)\n  [1,6,6,2,6,4,6,1,6,6,1,6]\n  ```\n\n- TODO\n\n  ```haskell\n  elements :: [a] -\u003e Gen a\n  ```\n\n  ```\n  ghci\u003e generate (elements ['a','e','i','o','u'])\n  'i'\n  ```\n\n- TODO\n\n  ```haskell\n  growingElements :: [a] -\u003e Gen a\n  ```\n\n- TODO\n\n  ```haskell\n  sized :: (Int -\u003e Gen a) -\u003e Gen a\n  ```\n\n- TODO\n\n  ```haskell\n  resize :: Int -\u003e Gen a -\u003e Gen a\n  ```\n\n- TODO\n\n  ```haskell\n  suchThat :: Gen a -\u003e (a -\u003e Bool) -\u003e Gen a\n  ```\n\n  ```\n  ghci\u003e generate (arbitrary `suchThat` even)\n  20\n  ```\n\n- TODO\n\n  ```haskell\n  suchThatMaybe :: Gen a -\u003e (a -\u003e Bool) -\u003e Gen (Maybe a)\n  ```\n\n- TODO\n\n  ```haskell\n  listOf :: Gen a -\u003e Gen [a]\n  ```\n\n  ```\n  ghci\u003e generate (listOf (elements ['a'..'z']))\n  \"xrgdxpjbsxpilmdfofhlgrsihvgsn\"\n  ```\n\n- TODO\n\n  ```haskell\n  listOf1 :: Gen a -\u003e Gen [a]\n  ```\n\n  ```\n  ghci\u003e generate (listOf1 (elements ['a'..'z']))\n  \"gxxg\"\n  ```\n\n- TODO\n\n  ```haskell\n  vectorOf :: Int -\u003e Gen a -\u003e Gen [a]\n  ```\n\n  ```\n  ghci\u003e generate (vectorOf 5 (elements ['a'..'z']))\n  \"wecoq\"\n  ```\n\n- TODO\n\n  ```haskell\n  infiniteListOf :: Gen a -\u003e Gen [a]\n  ```\n\n  ```\n  ghci\u003e generate (fmap null (infiniteListOf (arbitrary :: Gen Int)))\n  False\n  ```\n\n## Analysing test distribution\n\n### label\n\n```haskell\nlabel :: Testable prop =\u003e String -\u003e prop -\u003e Property\n```\n\nAttaches a label to a property used for reporting test case\ndistribution.\n\n### collect\n\n```haskell\ncollect :: (Show a, Testable prop) =\u003e a -\u003e prop -\u003e Property\n```\n\nlabels a property with a value, collect x = label (show x)\n\n### classify\n\n```haskell\nclassify :: Testable prop =\u003e Bool -\u003e String -\u003e prop -\u003e Property\n```\n\nconditionally labels test case\n\n### cover\n\n```haskell\ncover :: Testable prop =\u003e Bool -\u003e Int -\u003e String -\u003e prop -\u003e Property\n```\n\nchecks thta at least the given proportin of the test cases belong to\nthe given class\n\n[qc-man]: http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html\n\n[qc-2.7.6]: https://www.stackage.org/lts-2.18/package/QuickCheck-2.7.6\n[qc]: http://haddock.stackage.org/lts-2.18/QuickCheck-2.7.6/Test-QuickCheck.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackbuilders%2Fquickcheck-manual","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstackbuilders%2Fquickcheck-manual","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackbuilders%2Fquickcheck-manual/lists"}