{"id":741,"date":"2009-03-01T11:42:14","date_gmt":"2009-03-01T10:42:14","guid":{"rendered":"http:\/\/www.navision-blog.de\/2009\/03\/01\/testing-quicksort-with-naturalspec\/"},"modified":"2009-11-08T11:32:38","modified_gmt":"2009-11-08T10:32:38","slug":"testing-quicksort-with-naturalspec","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2009\/03\/01\/testing-quicksort-with-naturalspec\/","title":{"rendered":"Testing Quicksort with NaturalSpec"},"content":{"rendered":"<p>In my last article I showed two ways to use <a href=\"http:\/\/www.navision-blog.de\/2009\/02\/28\/parameterized-scenarios-with-naturalspec\/\">parameterized scenarios<\/a> in <a href=\"http:\/\/code.google.com\/p\/natural\/\">NaturalSpec<\/a>. This time I will show how we can combine both to test a small <a href=\"http:\/\/en.wikipedia.org\/wiki\/Quicksort\">Quicksort<\/a> function.<\/p>\n<p>First of all we define a scenario for sorting:<\/p>\n<pre class=\"code\"><span style=\"color: green\">\/\/\/ predefined sorting scenario\n<\/span><span style=\"color: blue\">let <\/span>sortingScenario f list =\n  Given list\n    |&gt; When sorting_with f\n    |&gt; It should be sorted\n    |&gt; It should contain_all_elements_from list\n    |&gt; It should contain_no_other_elements_than list<\/pre>\n<pre class=\"code\"><span style=\"color: green\">\/\/\/ predefined Quicksort scenario\n<\/span><span style=\"color: blue\">let <\/span>quicksortScenario list = sortingScenario QuickSort list<\/pre>\n<p>Now we define some concrete test cases:<\/p>\n<pre class=\"code\">[&lt;Scenario&gt;]\n<span style=\"color: blue\">let <\/span>When_sorting_empty_list() =\n  quicksortScenario []\n    |&gt; Verify\n    \n[&lt;Scenario&gt;]\n<span style=\"color: blue\">let <\/span>When_sorting_small_list() =\n  quicksortScenario [2;1;8;15;5;22]\n    |&gt; Verify      \n    \n[&lt;ScenarioTemplate(100)&gt;]\n[&lt;ScenarioTemplate(1000)&gt;]\n[&lt;ScenarioTemplate(2500)&gt;]\n<span style=\"color: blue\">let <\/span>When_sorting_ordered_list n =\n  quicksortScenario [1..n]\n    |&gt; Verify  \n    \n[&lt;ScenarioTemplate(100)&gt;]\n[&lt;ScenarioTemplate(1000)&gt;]\n[&lt;ScenarioTemplate(2500)&gt;]\n<span style=\"color: blue\">let <\/span>When_sorting_random_list n =\n  quicksortScenario (list_of_random_ints n)\n    |&gt; Verify  <\/pre>\n<p>After we defined our spec the task is now to implement the sorting function. I am using a very short (and very na\u00efve) Quicksort implementation in F#:<\/p>\n<pre class=\"code\"><span style=\"color: green\">\/\/\/ naive implementation of QuickSort - don't use it\n<\/span><span style=\"color: blue\">let rec <\/span>quicksort = <span style=\"color: blue\">function\n  <\/span>| [] <span style=\"color: blue\">-&gt; <\/span>[]\n  | pivot :: rest <span style=\"color: blue\">-&gt;\n     let <\/span>small,big = List.partition ((&gt;) pivot) rest\n     quicksort small @ [pivot] @ quicksort big\n     \n<span style=\"color: blue\">let <\/span>QuickSort x =\n  printMethod <span style=\"color: maroon\">&quot;&quot;\n  <\/span>quicksort x   <\/pre>\n<p>If we run the scenario, we get the following output (I shortened a bit):<\/p>\n<blockquote>\n<p>Scenario: When sorting empty list <\/p>\n<p>&#8211; Given []<br \/>\n    &#8211; When sorting with QuickSort<br \/>\n    =&gt; It should be sorted<br \/>\n    =&gt; It should contain all elements from []<br \/>\n    =&gt; It should contain no other elements than []<br \/>\n    ==&gt; Result is: []<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.0355s<\/p>\n<p>Scenario: When sorting small list<\/p>\n<p>&#8211; Given [2; 1; 8; 15; 5; 22]<br \/>\n    &#8211; When sorting with QuickSort<br \/>\n    =&gt; It should be sorted<br \/>\n    =&gt; It should contain all elements from [2; 1; 8; 15; 5; 22]<br \/>\n    =&gt; It should contain no other elements than [2; 1; 8; 15; 5; 22]<br \/>\n    ==&gt; Result is: [1; 2; 5; 8; 15; 22]<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.0065s<\/p>\n<p>Scenario: When sorting ordered list<\/p>\n<p>[\u2026]&#160; 100 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.0939s<\/p>\n<p>Scenario: When sorting ordered list<\/p>\n<p>[\u2026]&#160; 1000 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.7130s<\/p>\n<p>Scenario: When sorting ordered list<\/p>\n<p>[\u2026]&#160; 2500 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 3.0631s<\/p>\n<p>Scenario: When sorting random list <\/p>\n<p>[\u2026]&#160; 100 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.0485s<\/p>\n<p>Scenario: When sorting random list<\/p>\n<p>[\u2026]&#160; 1000 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.1878s<\/p>\n<p>Scenario: When sorting random list<\/p>\n<p>[\u2026]&#160; 1000 elements<br \/>\n    ==&gt; OK<br \/>\n    ==&gt; Time: 0.8713s<\/p>\n<\/blockquote>\n<p>As you can see the function is much faster if we sort a random list. This is because of the na\u00efve choice of the pivot element.<\/p>\n<p>I don\u2019t want to give better implementations here (use <a href=\"http:\/\/msdn.microsoft.com\/en-us\/vcsharp\/aa336756.aspx#simple1\">LINQ<\/a> or <a href=\"http:\/\/blogs.msdn.com\/pfxteam\/archive\/2008\/06\/11\/8592301.aspx\">PLINQ<\/a>). I just wanted to show how we can easily verify a test function with NaturalSpec.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last article I showed two ways to use parameterized scenarios in NaturalSpec. This time I will show how we can combine both to test a small Quicksort function. First of all we define a scenario for sorting: \/\/\/ predefined sorting scenario let sortingScenario f list = Given list |&gt; When sorting_with f |&gt; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[448,524],"tags":[664,666,539],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/741"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=741"}],"version-history":[{"count":6,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/741\/revisions"}],"predecessor-version":[{"id":922,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/741\/revisions\/922"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=741"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}