PageSourceSearch

https://kotest.io/assets/js/bf7fb936.be8d3c68.js

js kotest.io collected 2026-10-03 21:52:11 UTC 6,886 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkkotestdocs=globalThis.webpackChunkkotestdocs||[]).push([[1728],{13270(e,t,n){n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"proptest/testfunctions","title":"Property Test Functions","description":"There are two variants of functions that are used to execute a property test in Kotest: forAll and checkAll.","source":"@site/versioned_docs/version-5.3.x/proptest/test_functions.md","sourceDirName":"proptest","slug":"/proptest/property-test-functions.html","permalink":"/docs/5.3.x/proptest/property-test-functions.html","draft":false,"unlisted":false,"editUrl":"https://github.com/kotest/kotest/blob/master/documentation/versioned_docs/version-5.3.x/proptest/test_functions.md","tags":[],"version":"5.3.x","frontMatter":{"id":"testfunctions","title":"Property Test Functions","slug":"property-test-functions.html","sidebar_label":"Test Functions"},"sidebar":"proptest","previous":{"title":"Introduction","permalink":"/docs/5.3.x/proptest/property-based-testing.html"},"next":{"title":"Generators","permalink":"/docs/5.3.x/proptest/property-test-generators.html"}}');var r=n(74848),o=n(28453);const i={id:"testfunctions",title:"Property Test Functions",slug:"property-test-functions.html",sidebar_label:"Test Functions"},a=void 0,l={},c=[{value:"For All",id:"for-all",level:3},{value:"Check All",id:"check-all",level:3},{value:"Iterations",id:"iterations",level:3},{value:"Specifying Generators",id:"specifying-generators",level:3}];function p(e){const t={a:"a",code:"code",em:"em",h3:"h3",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["There are two variants of functions that are used to execute a property test in Kotest: ",(0,r.jsx)(t.code,{children:"forAll"})," and ",(0,r.jsx)(t.code,{children:"checkAll"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"for-all",children:"For All"}),"\n",(0,r.jsxs)(t.p,{children:["The first, ",(0,r.jsx)(t.code,{children:"forAll"}),", accepts an n-arity function ",(0,r.jsx)(t.code,{children:"(a, ..., n) -> Boolean"})," that tests the property.\nThe test will pass if, for all input values, the function returns true."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-kotlin",children:'class PropertyExample: StringSpec({\n   "String size" {\n      forAll<String, String> { a, b ->\n         (a + b).length == a.length + b.length\n      }\n   }\n})\n'})}),"\n",(0,r.jsxs)(t.p,{children:["Notice that this functions accepts type parameters for the argument types, with arity up to 14.\nKotest uses these type parameters to locate a ",(0,r.jsx)(t.em,{children:"generator"})," which provides (generates) random values of a suitable type."]}),"\n",(0,r.jsxs)(t.p,{children:["For example, ",(0,r.jsx)(t.code,{children:"forAll<String, Int, Boolean> { a, b, c -> }"})," is a 3-arity property test where\nargument ",(0,r.jsx)(t.code,{children:"a"})," is a random String, argument ",(0,r.jsx)(t.code,{children:"b"})," is a random int, and argument ",(0,r.jsx)(t.code,{children:"c"})," is a random boolean."]}),"\n",(0,r.jsx)(t.h3,{id:"check-all",children:"Check All"}),"\n",(0,r.jsxs)(t.p,{children:["The second, ",(0,r.jsx)(t.code,{children:"checkAll"}),", accepts an n-arity function ",(0,r.jsx)(t.code,{children:"(a, ..., n) -> Unit"})," in which you can simply execute assertions against the inputs.\nThis approach will consider a test valid if no exceptions are thrown.\nHere is the same example again written in the equivalent way using checkAll."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-kotlin",children:'class PropertyExample: StringSpec({\n   "String size" {\n      checkAll<String, String> { a, b ->\n         a + b shouldHaveLength a.length + b.length\n      }\n   }\n})\n'})}),"\n",(0,r.jsx)(t.p,{children:"The second approach is more general purpose than returning a boolean, but the first approach is from the original\nhaskell libraries that inspired this library."}),"\n",(0,r.jsx)(t.h3,{id:"iterations",children:"Iterations"}),"\n",(0,r.jsx)(t.p,{children:"By default, Kotest will run the property test 1000 times. We can easily customize this by specifying the iteration count\nwhen invoking the test method."}),"\n",(0,r.jsx)(t.p,{children:"Let's say we want to run a test 10,000 times."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-kotlin",children:'class PropertyExample: StringSpec({\n   "a many iterations test" {\n      checkAll<Double, Double>(10_000) { a, b ->\n         // test here\n      }\n   }\n})\n'})}),"\n",(0,r.jsx)(t.h3,{id:"specifying-generators",children:"Specifying Generators"}),"\n",(0,r.jsxs)(t.p,{children:["You saw in the previous examples that Kotest would provide values automatically based on the type parameter(s).\nIt does this by locating a ",(0,r.jsx)(t.em,{children:"generator"})," that generates values for the required type."]}),"\n",(0,r.jsxs)(t.p,{children:["For example, the automatically provided ",(0,r.jsx)(t.em,{children:"Integer"})," generator generates random ints from all possible values -\nnegative, positive, infinities, zero and so on."]}),"\n",(0,r.jsx)(t.p,{children:"This is fine for basic tests but often we want more control over the sample space.\nFor example, we may want to test a function for numbers in a certain range only."}
1),"\n",(0,r.jsx)(t.p,{children:"Then you would need to specify the generator(s) manually."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-kotlin",children:'class PropertyExample: StringSpec({\n   "is allowed to drink in Chicago" {\n      forAll(Arb.int(21..150)) { a ->\n         isDrinkingAge(a) // assuming some function that calculates if we\'re old enough to drink\n      }\n   }\n   "is allowed to drink in London" {\n      forAll(Arb.int(18..150)) { a ->\n         isDrinkingAge(a) // assuming some function that calculates if we\'re old enough to drink\n      }\n   }\n})\n'})}),"\n",(0,r.jsxs)(t.p,{children:["You can see we created two tests and in each test passed a generator into the ",(0,r.jsx)(t.code,{children:"forAll"})," function with a suitable int range."]}),"\n",(0,r.jsxs)(t.p,{children:["See ",(0,r.jsx)(t.a,{href:"/docs/5.3.x/proptest/property-test-generators.html",children:"here"})," for a list of the built in generators."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453(e,t,n){n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.