{"id":2802,"date":"2015-02-02T21:50:30","date_gmt":"2015-02-02T21:50:30","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2802"},"modified":"2015-02-02T21:50:30","modified_gmt":"2015-02-02T21:50:30","slug":"randomly-generating-test-data-using-fscheck","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/randomly-generating-test-data-using-fscheck\/","title":{"rendered":"Randomly generating test data using FsCheck"},"content":{"rendered":"<p>My latest small project is to write a bunch of conversion functions in F#. Basically I want to convert things like, weights from kg to stones. Metres to feet and so on.<\/p>\n<p>I wrote a couple of tests to ensure that the conversions were as expected, but ofcourse with such a set of functions and the wide range of values one might pass to them, my tests simply confirmed a couple of values were correct. It&#8217;d be nice to feel like I could say <em>this function is valid for all values within the range x to y<\/em>.<\/p>\n<p>This is where FsCheck can help.<\/p>\n<p><em>To use FsCheck just use nuget and search for FsCheck, I also use XUnit so chose FsCheck with XUnit support.<\/em><\/p>\n<p>With FsCheck we create properties which define a valid state for a test, so for example if I have a function toMillimetres and another toKilometres, then we can expect that for every value entered into toMillimetres the function toKilometres will return the original value.<\/p>\n<p>This can therefore be described as a property.<\/p>\n<p><em>At this point we also need to beware that if the calculations involve floating point numbers we may not get back exactly the value we entered, so we&#8217;d use something like FsUnit to add a &#8220;tolerance&#8221; to the formula, i.e. it&#8217;s within 0.1 of the expected answer.<\/em><\/p>\n<p>Let&#8217;s look at some code<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\n&#x5B;&lt;Property&gt;]\r\nlet ``From kilometre to millimetre and back`` () =\r\n   let property value = \r\n      let millimetres = km.toMillimetres (km.create value)\r\n      let kilometres = mm.toKilometres millimetres\r\n\r\n      kilometres\r\n      |&gt; should (equalWithin 0.1) value\r\n\r\n   Check.QuickThrowOnFailure (testRange property)\r\n<\/pre>\n<p>So I&#8217;ve created an FsCheck property test named <em>From kilometre to millimetre and back<\/em> the idea being that (as previously stated) we can put a value into the toMillimetres function then put the result into the toKilometres function and expect (within a tolerance of 0.1) the value to be the same as the resultant kilometres.<\/p>\n<p>The function Check.QuickThrowOnFailure takes our property and in this case, because I wanted to limit the range of the testing, the property goes through the function testRange (which is nothing very exciting) but I&#8217;ve listed it below for completeness<\/p>\n<pre class=\"brush: fsharp; title: ; notranslate\" title=\"\">\r\nlet testRange f value =\r\n   let inRange v = (v &gt; -1E+10) &amp;&amp; (v &lt; 1E+10)\r\n   inRange value ==&gt; lazy (f value)\r\n<\/pre>\n<p>The above code simple takes a function f (the property function from the test) and is supplied a value via FsCheck. We then simply ensure the value is within the range -1E+10 to 1E+10 by calling the inRange inner function.<\/p>\n<p>Now when we run this property via FsCheck it will pass multiple values into the property function within the range we&#8217;ve defined and runs the unit test.<\/p>\n<p><em>Note: In the property code I&#8217;m using FsCheck with XUnit and FsUnit with Xunit.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>My latest small project is to write a bunch of conversion functions in F#. Basically I want to convert things like, weights from kg to stones. Metres to feet and so on. I wrote a couple of tests to ensure that the conversions were as expected, but ofcourse with such a set of functions and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6],"tags":[],"class_list":["post-2802","post","type-post","status-publish","format-standard","hentry","category-f"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=2802"}],"version-history":[{"count":7,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2802\/revisions"}],"predecessor-version":[{"id":2836,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2802\/revisions\/2836"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}