test_case_generation.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Data-driven test cases</title>
  5. <link rel="stylesheet" href="../../../boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../../../index.html" title="Boost.Test">
  8. <link rel="up" href="../test_cases.html" title="Test cases">
  9. <link rel="prev" href="test_organization_nullary.html" title="Test cases without parameters">
  10. <link rel="next" href="test_case_generation/datasets.html" title="Datasets">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="test_organization_nullary.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../test_cases.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="test_case_generation/datasets.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h4 class="title">
  27. <a name="boost_test.tests_organization.test_cases.test_case_generation"></a><a class="link" href="test_case_generation.html" title="Data-driven test cases">Data-driven
  28. test cases</a>
  29. </h4></div></div></div>
  30. <div class="toc"><dl class="toc">
  31. <dt><span class="section"><a href="test_case_generation/datasets.html">Datasets</a></span></dt>
  32. <dd><dl>
  33. <dt><span class="section"><a href="test_case_generation/datasets.html#boost_test.tests_organization.test_cases.test_case_generation.datasets.dataset_interface">Dataset
  34. interface</a></span></dt>
  35. <dt><span class="section"><a href="test_case_generation/datasets.html#boost_test.tests_organization.test_cases.test_case_generation.datasets.dataset_creation_and_delayed_cre">Dataset
  36. creation and delayed creation</a></span></dt>
  37. </dl></dd>
  38. <dt><span class="section"><a href="test_case_generation/datasets_auto_registration.html">Declaring
  39. and registering test cases with datasets</a></span></dt>
  40. <dt><span class="section"><a href="test_case_generation/operations.html">Operations
  41. on dataset</a></span></dt>
  42. <dd><dl>
  43. <dt><span class="section"><a href="test_case_generation/operations.html#boost_test.tests_organization.test_cases.test_case_generation.operations.joins">Joins</a></span></dt>
  44. <dt><span class="section"><a href="test_case_generation/operations.html#boost_test.tests_organization.test_cases.test_case_generation.operations.zips">Zips</a></span></dt>
  45. <dt><span class="section"><a href="test_case_generation/operations.html#boost_test.tests_organization.test_cases.test_case_generation.operations.grid_cartesian_products">Grid
  46. (Cartesian products)</a></span></dt>
  47. </dl></dd>
  48. <dt><span class="section"><a href="test_case_generation/generators.html">Datasets
  49. generators</a></span></dt>
  50. </dl></div>
  51. <h5>
  52. <a name="boost_test.tests_organization.test_cases.test_case_generation.h0"></a>
  53. <span class="phrase"><a name="boost_test.tests_organization.test_cases.test_case_generation.why_data_driven_test_cases"></a></span><a class="link" href="test_case_generation.html#boost_test.tests_organization.test_cases.test_case_generation.why_data_driven_test_cases">Why
  54. data-driven test cases?</a>
  55. </h5>
  56. <p>
  57. Some tests are required to be repeated for a series of different input
  58. parameters. One way to achieve this is manually register a test case for
  59. each parameter. You can also invoke a test function with all parameters
  60. manually from within your test case, like this:
  61. </p>
  62. <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">single_test</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">)</span>
  63. <span class="special">{</span>
  64. <a class="link" href="../../utf_reference/testing_tool_ref/assertion_boost_test_universal_macro.html" title="BOOST_TEST"><code class="computeroutput"><span class="identifier">BOOST_TEST</span></code></a><span class="special">(</span> <span class="comment">/* test assertion */</span> <span class="special">);</span>
  65. <span class="special">}</span>
  66. <span class="keyword">void</span> <span class="identifier">combined_test</span><span class="special">()</span>
  67. <span class="special">{</span>
  68. <span class="keyword">int</span> <span class="identifier">params</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span> <span class="special">};</span>
  69. <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span> <span class="identifier">params</span><span class="special">,</span> <span class="identifier">params</span><span class="special">+</span><span class="number">5</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">single_test</span> <span class="special">);</span>
  70. <span class="special">}</span>
  71. </pre>
  72. <p>
  73. The approach above has several drawbacks:
  74. </p>
  75. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  76. <li class="listitem">
  77. the logic for running the tests is inside a test itself: <code class="computeroutput"><span class="identifier">single_test</span></code> in the above example
  78. is run from the test case <code class="computeroutput"><span class="identifier">combined_test</span></code>
  79. while its execution would be better handled by the <span class="emphasis"><em>Unit Test
  80. Framework</em></span>
  81. </li>
  82. <li class="listitem">
  83. in case of fatal failure for one of the values in <code class="computeroutput"><span class="identifier">param</span></code>
  84. array above (say a failure in <a class="link" href="../../utf_reference/testing_tool_ref/assertion_boost_test_universal_macro.html" title="BOOST_TEST"><code class="computeroutput"><span class="identifier">BOOST_TEST_REQUIRE</span></code></a>), the test
  85. <code class="computeroutput"><span class="identifier">combined_test</span></code> is aborted
  86. and the next test-case in the test tree is executed.
  87. </li>
  88. <li class="listitem">
  89. in case of failure, the reporting is not accurate enough: the test
  90. should certainly be reran during debugging sessions by a human or additional
  91. logic for reporting should be implemented in the test itself.
  92. </li>
  93. </ul></div>
  94. <h5>
  95. <a name="boost_test.tests_organization.test_cases.test_case_generation.h1"></a>
  96. <span class="phrase"><a name="boost_test.tests_organization.test_cases.test_case_generation.parameter_generation_scalability"></a></span><a class="link" href="test_case_generation.html#boost_test.tests_organization.test_cases.test_case_generation.parameter_generation_scalability">Parameter
  97. generation, scalability and composition</a>
  98. </h5>
  99. <p>
  100. In some circumstance, one would like to run a parametrized test over an
  101. <span class="emphasis"><em>arbitrary large</em></span> set of values. Enumerating the parameters
  102. by hand is not a solution that scales well, especially when these parameters
  103. can be described in another function that generates these values. However,
  104. this solution has also limitations
  105. </p>
  106. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  107. <li class="listitem">
  108. <span class="bold"><strong>Generating functions</strong></span>: suppose we have
  109. a function <code class="computeroutput"><span class="identifier">func</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">f</span><span class="special">)</span></code>, where <code class="computeroutput"><span class="identifier">f</span></code>
  110. is any number in [0, 1]. We are not interested that much in the exact
  111. value, but we would like to test <code class="computeroutput"><span class="identifier">func</span></code>.
  112. What about, instead of writing the <code class="computeroutput"><span class="identifier">f</span></code>
  113. for which <code class="computeroutput"><span class="identifier">func</span></code> will
  114. be tested against, we choose randomly <code class="computeroutput"><span class="identifier">f</span></code>
  115. in [0, 1]? And also what about instead of having only one value for
  116. <code class="computeroutput"><span class="identifier">f</span></code>, we run the test
  117. on arbitrarily many numbers? We easily understand from this small example
  118. that tests requiring parameters are more powerful when, instead of
  119. writing down constant values in the test, a generating function is
  120. provided.
  121. </li>
  122. <li class="listitem">
  123. <span class="bold"><strong>Scalability</strong></span>: suppose we have a test
  124. case on <code class="computeroutput"><span class="identifier">func1</span></code>, on which
  125. we test <code class="computeroutput"><span class="identifier">N</span></code> values written
  126. as constant in the test file. What does the test ensure? We have the
  127. guaranty that <code class="computeroutput"><span class="identifier">func1</span></code>
  128. is working on these <code class="computeroutput"><span class="identifier">N</span></code>
  129. values. Yet in this setting <code class="computeroutput"><span class="identifier">N</span></code>
  130. is necessarily finite and usually small. How would we extend or scale
  131. <code class="computeroutput"><span class="identifier">N</span></code> easily? One solution
  132. is to be able to generate new values, and to be able to define a test
  133. on the <span class="bold"><strong>class</strong></span> of possible inputs for
  134. <code class="computeroutput"><span class="identifier">func1</span></code> on which the
  135. function should have a defined behavior. To some extent, <code class="computeroutput"><span class="identifier">N</span></code> constant written down in the test
  136. are just an excerpt of the possible inputs of <code class="computeroutput"><span class="identifier">func1</span></code>,
  137. and working on the class of inputs gives more flexibility and power
  138. to the test.
  139. </li>
  140. <li class="listitem">
  141. <p class="simpara">
  142. <span class="bold"><strong>Composition</strong></span>: suppose we already have
  143. test cases for two functions <code class="computeroutput"><span class="identifier">func1</span></code>
  144. and <code class="computeroutput"><span class="identifier">func2</span></code>, taking as
  145. argument the types <code class="computeroutput"><span class="identifier">T1</span></code>
  146. and <code class="computeroutput"><span class="identifier">T2</span></code> respectively.
  147. Now we would like to test a new functions <code class="computeroutput"><span class="identifier">func3</span></code>
  148. that takes as argument a type <code class="computeroutput"><span class="identifier">T3</span></code>
  149. containing <code class="computeroutput"><span class="identifier">T1</span></code> and
  150. <code class="computeroutput"><span class="identifier">T2</span></code>, and calling <code class="computeroutput"><span class="identifier">func1</span></code> and <code class="computeroutput"><span class="identifier">func2</span></code>
  151. through a known algorithm. An example of such a setting would be
  152. </p>
  153. <pre class="programlisting"><span class="comment">// Returns the log of x</span>
  154. <span class="comment">// Precondition: x strictly positive.</span>
  155. <span class="keyword">double</span> <span class="identifier">fast_log</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">);</span>
  156. <span class="comment">// Returns 1/(x-1)</span>
  157. <span class="comment">// Precondition: x != 1</span>
  158. <span class="keyword">double</span> <span class="identifier">fast_inv</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">);</span>
  159. <span class="keyword">struct</span> <span class="identifier">dummy</span> <span class="special">{</span>
  160. <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">field1</span><span class="special">;</span>
  161. <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">field2</span><span class="special">;</span>
  162. <span class="special">};</span>
  163. <span class="keyword">double</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">dummy</span> <span class="identifier">value</span><span class="special">)</span>
  164. <span class="special">{</span>
  165. <span class="keyword">return</span> <span class="number">0.5</span> <span class="special">*</span> <span class="special">(</span><span class="identifier">exp</span><span class="special">(</span><span class="identifier">fast_log</span><span class="special">(</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">field1</span><span class="special">))/</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">field1</span> <span class="special">+</span> <span class="identifier">value</span><span class="special">.</span><span class="identifier">field2</span><span class="special">/</span><span class="identifier">fast_inv</span><span class="special">(</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">field2</span><span class="special">));</span>
  166. <span class="special">}</span>
  167. </pre>
  168. <p class="simpara">
  169. In this example,
  170. </p>
  171. <p class="simpara">
  172. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
  173. <li class="listitem">
  174. <code class="computeroutput"><span class="identifier">func3</span></code> inherits
  175. from the preconditions of <code class="computeroutput"><span class="identifier">fast_log</span></code>
  176. and <code class="computeroutput"><span class="identifier">fast_inv</span></code>:
  177. it is defined in <code class="computeroutput"><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="special">+</span><span class="identifier">infinity</span><span class="special">)</span></code> and in <code class="computeroutput"><span class="special">[-</span><span class="identifier">C</span><span class="special">,</span>
  178. <span class="special">+</span><span class="identifier">C</span><span class="special">]</span> <span class="special">-</span>
  179. <span class="special">{</span><span class="number">1</span><span class="special">}</span></code> for <code class="computeroutput"><span class="identifier">field1</span></code>
  180. and <code class="computeroutput"><span class="identifier">field2</span></code> respectively
  181. (<code class="computeroutput"><span class="identifier">C</span></code> being a constant
  182. arbitrarily big).
  183. </li>
  184. <li class="listitem">
  185. as defined above, <code class="computeroutput"><span class="identifier">func3</span></code>
  186. should be close to 1 everywhere on its definition domain.
  187. </li>
  188. <li class="listitem">
  189. we would like to reuse the properties of <code class="computeroutput"><span class="identifier">fast_log</span></code>
  190. and <code class="computeroutput"><span class="identifier">fast_inv</span></code>
  191. in the compound function <code class="computeroutput"><span class="identifier">func3</span></code>
  192. and assert that <code class="computeroutput"><span class="identifier">func3</span></code>
  193. is well defined over an arbitrary large definition domain.
  194. </li>
  195. </ul></div>
  196. </p>
  197. <p class="simpara">
  198. Having parametrized tests on <code class="computeroutput"><span class="identifier">func3</span></code>
  199. hardly tells us about the possible numerical properties or instabilities
  200. close to the point <code class="computeroutput"><span class="special">{</span><span class="identifier">field1</span>
  201. <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">field2</span>
  202. <span class="special">=</span> <span class="number">1</span><span class="special">}</span></code>. Indeed, the parametrized test may
  203. test for some points around (0,1), but will fail to provide an <span class="bold"><strong>asymptotic behavior</strong></span> of the function close to
  204. this point.
  205. </p>
  206. </li>
  207. </ul></div>
  208. <h5>
  209. <a name="boost_test.tests_organization.test_cases.test_case_generation.h2"></a>
  210. <span class="phrase"><a name="boost_test.tests_organization.test_cases.test_case_generation.data_driven_tests_in_the_boost_t"></a></span><a class="link" href="test_case_generation.html#boost_test.tests_organization.test_cases.test_case_generation.data_driven_tests_in_the_boost_t">Data
  211. driven tests in the Boost.Test framework</a>
  212. </h5>
  213. <p>
  214. The facilities provided by the <span class="emphasis"><em>Unit Test Framework</em></span>
  215. addressed the issues described above:
  216. </p>
  217. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  218. <li class="listitem">
  219. the notion of <span class="bold"><strong>datasets</strong></span> eases the description
  220. of the class of inputs for test cases. The datasets also implement
  221. several operations that enable their combinations to create new, more
  222. complex datasets,
  223. </li>
  224. <li class="listitem">
  225. two macros, <a class="link" href="../../utf_reference/test_org_reference/test_org_boost_test_dataset.html" title="BOOST_DATA_TEST_CASE"><code class="computeroutput"><span class="identifier">BOOST_DATA_TEST_CASE</span></code></a> and
  226. <a class="link" href="../../utf_reference/test_org_reference/test_org_boost_test_dataset_fixture.html" title="BOOST_DATA_TEST_CASE_F"><code class="computeroutput"><span class="identifier">BOOST_DATA_TEST_CASE_F</span></code></a>, respectively
  227. without and with fixture support, are used for the declaration and
  228. registration of a test case over a collection of values (samples),
  229. </li>
  230. <li class="listitem">
  231. each test case, associated to a unique value, is executed independently
  232. from others. These tests are guarded in the same way regular test cases
  233. are, which makes the execution of the tests over each sample of a dataset
  234. isolated, robust, repeatable and ease the debugging,
  235. </li>
  236. <li class="listitem">
  237. several datasets generating functions are provided by the <span class="emphasis"><em>Unit
  238. Test Framework</em></span>
  239. </li>
  240. </ul></div>
  241. <p>
  242. The remainder of this section covers the notions and feature provided by
  243. the <span class="emphasis"><em>Unit Test Framework</em></span> about the data-driven test
  244. cases, in particular:
  245. </p>
  246. <div class="orderedlist"><ol class="orderedlist" type="1">
  247. <li class="listitem">
  248. the notion of <a class="link" href="test_case_generation/datasets.html" title="Datasets"><span class="bold"><strong>dataset</strong></span> and <span class="bold"><strong>sample</strong></span></a>
  249. is introduced
  250. </li>
  251. <li class="listitem">
  252. <a class="link" href="test_case_generation/datasets_auto_registration.html" title="Declaring and registering test cases with datasets">the
  253. declaration and registration</a> of the data-driven test cases are
  254. explained,
  255. </li>
  256. <li class="listitem">
  257. the <a class="link" href="test_case_generation/operations.html" title="Operations on dataset"><span class="emphasis"><em>operations</em></span></a>
  258. on datasets are detailed
  259. </li>
  260. <li class="listitem">
  261. and finally the built-in <a class="link" href="test_case_generation/generators.html" title="Datasets generators">dataset
  262. generators</a> are introduced.
  263. </li>
  264. </ol></div>
  265. </div>
  266. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  267. <td align="left"></td>
  268. <td align="right"><div class="copyright-footer">Copyright &#169; 2001-2019 Boost.Test
  269. contributors<p>
  270. Distributed under the Boost Software License, Version 1.0. (See accompanying
  271. file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  272. </p>
  273. </div></td>
  274. </tr></table>
  275. <hr>
  276. <div class="spirit-nav">
  277. <a accesskey="p" href="test_organization_nullary.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../test_cases.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="test_case_generation/datasets.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
  278. </div>
  279. </body>
  280. </html>