]> git.llucax.com Git - personal/website.git/blob - source/proj/mutest/releases/manual-1.0.html
resume: Fix working experience
[personal/website.git] / source / proj / mutest / releases / manual-1.0.html
1 <?xml version="1.0" encoding="utf-8" ?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
7 <title>mutest - A simple micro unit testing framework for C</title>
8 <meta name="author" content="Leandro Lucarella" />
9 <meta name="date" content="2008-12-25" />
10 <meta name="copyright" content="Leandro Lucarella (2008), released under the BOLA license" />
11 <style type="text/css">
12
13 /*
14 :Author: David Goodger (goodger@python.org)
15 :Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $
16 :Copyright: This stylesheet has been placed in the public domain.
17
18 Default cascading style sheet for the HTML output of Docutils.
19
20 See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
21 customize this style sheet.
22 */
23
24 /* used to remove borders from tables and images */
25 .borderless, table.borderless td, table.borderless th {
26   border: 0 }
27
28 table.borderless td, table.borderless th {
29   /* Override padding for "table.docutils td" with "! important".
30      The right padding separates the table cells. */
31   padding: 0 0.5em 0 0 ! important }
32
33 .first {
34   /* Override more specific margin styles with "! important". */
35   margin-top: 0 ! important }
36
37 .last, .with-subtitle {
38   margin-bottom: 0 ! important }
39
40 .hidden {
41   display: none }
42
43 a.toc-backref {
44   text-decoration: none ;
45   color: black }
46
47 blockquote.epigraph {
48   margin: 2em 5em ; }
49
50 dl.docutils dd {
51   margin-bottom: 0.5em }
52
53 /* Uncomment (and remove this text!) to get bold-faced definition list terms
54 dl.docutils dt {
55   font-weight: bold }
56 */
57
58 div.abstract {
59   margin: 2em 5em }
60
61 div.abstract p.topic-title {
62   font-weight: bold ;
63   text-align: center }
64
65 div.admonition, div.attention, div.caution, div.danger, div.error,
66 div.hint, div.important, div.note, div.tip, div.warning {
67   margin: 2em ;
68   border: medium outset ;
69   padding: 1em }
70
71 div.admonition p.admonition-title, div.hint p.admonition-title,
72 div.important p.admonition-title, div.note p.admonition-title,
73 div.tip p.admonition-title {
74   font-weight: bold ;
75   font-family: sans-serif }
76
77 div.attention p.admonition-title, div.caution p.admonition-title,
78 div.danger p.admonition-title, div.error p.admonition-title,
79 div.warning p.admonition-title {
80   color: red ;
81   font-weight: bold ;
82   font-family: sans-serif }
83
84 /* Uncomment (and remove this text!) to get reduced vertical space in
85    compound paragraphs.
86 div.compound .compound-first, div.compound .compound-middle {
87   margin-bottom: 0.5em }
88
89 div.compound .compound-last, div.compound .compound-middle {
90   margin-top: 0.5em }
91 */
92
93 div.dedication {
94   margin: 2em 5em ;
95   text-align: center ;
96   font-style: italic }
97
98 div.dedication p.topic-title {
99   font-weight: bold ;
100   font-style: normal }
101
102 div.figure {
103   margin-left: 2em ;
104   margin-right: 2em }
105
106 div.footer, div.header {
107   clear: both;
108   font-size: smaller }
109
110 div.line-block {
111   display: block ;
112   margin-top: 1em ;
113   margin-bottom: 1em }
114
115 div.line-block div.line-block {
116   margin-top: 0 ;
117   margin-bottom: 0 ;
118   margin-left: 1.5em }
119
120 div.sidebar {
121   margin: 0 0 0.5em 1em ;
122   border: medium outset ;
123   padding: 1em ;
124   background-color: #ffffee ;
125   width: 40% ;
126   float: right ;
127   clear: right }
128
129 div.sidebar p.rubric {
130   font-family: sans-serif ;
131   font-size: medium }
132
133 div.system-messages {
134   margin: 5em }
135
136 div.system-messages h1 {
137   color: red }
138
139 div.system-message {
140   border: medium outset ;
141   padding: 1em }
142
143 div.system-message p.system-message-title {
144   color: red ;
145   font-weight: bold }
146
147 div.topic {
148   margin: 2em }
149
150 h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
151 h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
152   margin-top: 0.4em }
153
154 h1.title {
155   text-align: center }
156
157 h2.subtitle {
158   text-align: center }
159
160 hr.docutils {
161   width: 75% }
162
163 img.align-left {
164   clear: left }
165
166 img.align-right {
167   clear: right }
168
169 ol.simple, ul.simple {
170   margin-bottom: 1em }
171
172 ol.arabic {
173   list-style: decimal }
174
175 ol.loweralpha {
176   list-style: lower-alpha }
177
178 ol.upperalpha {
179   list-style: upper-alpha }
180
181 ol.lowerroman {
182   list-style: lower-roman }
183
184 ol.upperroman {
185   list-style: upper-roman }
186
187 p.attribution {
188   text-align: right ;
189   margin-left: 50% }
190
191 p.caption {
192   font-style: italic }
193
194 p.credits {
195   font-style: italic ;
196   font-size: smaller }
197
198 p.label {
199   white-space: nowrap }
200
201 p.rubric {
202   font-weight: bold ;
203   font-size: larger ;
204   color: maroon ;
205   text-align: center }
206
207 p.sidebar-title {
208   font-family: sans-serif ;
209   font-weight: bold ;
210   font-size: larger }
211
212 p.sidebar-subtitle {
213   font-family: sans-serif ;
214   font-weight: bold }
215
216 p.topic-title {
217   font-weight: bold }
218
219 pre.address {
220   margin-bottom: 0 ;
221   margin-top: 0 ;
222   font-family: serif ;
223   font-size: 100% }
224
225 pre.literal-block, pre.doctest-block {
226   margin-left: 2em ;
227   margin-right: 2em }
228
229 span.classifier {
230   font-family: sans-serif ;
231   font-style: oblique }
232
233 span.classifier-delimiter {
234   font-family: sans-serif ;
235   font-weight: bold }
236
237 span.interpreted {
238   font-family: sans-serif }
239
240 span.option {
241   white-space: nowrap }
242
243 span.pre {
244   white-space: pre }
245
246 span.problematic {
247   color: red }
248
249 span.section-subtitle {
250   /* font-size relative to parent (h1..h6 element) */
251   font-size: 80% }
252
253 table.citation {
254   border-left: solid 1px gray;
255   margin-left: 1px }
256
257 table.docinfo {
258   margin: 2em 4em }
259
260 table.docutils {
261   margin-top: 0.5em ;
262   margin-bottom: 0.5em }
263
264 table.footnote {
265   border-left: solid 1px black;
266   margin-left: 1px }
267
268 table.docutils td, table.docutils th,
269 table.docinfo td, table.docinfo th {
270   padding-left: 0.5em ;
271   padding-right: 0.5em ;
272   vertical-align: top }
273
274 table.docutils th.field-name, table.docinfo th.docinfo-name {
275   font-weight: bold ;
276   text-align: left ;
277   white-space: nowrap ;
278   padding-left: 0 }
279
280 h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
281 h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
282   font-size: 100% }
283
284 ul.auto-toc {
285   list-style-type: none }
286
287 </style>
288 </head>
289 <body>
290 <div class="document" id="mutest-a-simple-micro-unit-testing-framework-for-c">
291 <h1 class="title"><em>mutest</em> - A simple micro unit testing framework for C</h1>
292 <table class="docinfo" frame="void" rules="none">
293 <col class="docinfo-name" />
294 <col class="docinfo-content" />
295 <tbody valign="top">
296 <tr><th class="docinfo-name">Author:</th>
297 <td>Leandro Lucarella</td></tr>
298 <tr><th class="docinfo-name">Contact:</th>
299 <td><a class="first last reference external" href="mailto:llucax&#64;gmail.com">llucax&#64;gmail.com</a></td></tr>
300 <tr><th class="docinfo-name">Version:</th>
301 <td>1.0</td></tr>
302 <tr><th class="docinfo-name">Date:</th>
303 <td>2008-12-25</td></tr>
304 <tr><th class="docinfo-name">Copyright:</th>
305 <td>Leandro Lucarella (2008), released under the <a class="reference external" href="http://blitiri.com.ar/p/bola/">BOLA</a> license</td></tr>
306 </tbody>
307 </table>
308 <div class="abstract topic">
309 <p class="topic-title first">Abstract</p>
310 <p><em>mutest</em> is a micro <a class="reference external" href="http://en.wikipedia.org/wiki/Unit_testing">unit testing</a> framework for C (with some
311 <a class="reference internal" href="#c-support">C++ support</a>). It's mostly an idea (it even comes with
312 2 <a class="reference internal" href="#implementations">implementations</a> of the idea!) with the goal of being easy to use
313 (just write your <a class="reference internal" href="#test-case">test cases</a> grouped in <a class="reference internal" href="#test-suite">test suites</a> and you're
314 set) and so small and simple that you don't mind to copy the files to
315 your project and just use it (i.e., no dependencies).</p>
316 <p>The idea is simple: a source file is a <a class="reference internal" href="#test-suite">test suite</a>, a function is
317 a <a class="reference internal" href="#test-case">test case</a> (special functions can be used for <a class="reference internal" href="#test-suite">test suite</a>
318 <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a>), which can can have several <a class="reference internal" href="#checks">checks</a>.
319 <a class="reference internal" href="#checks">Checks</a> comes in 2 flavors, one that only prints an error, and one that
320 terminates the current <a class="reference internal" href="#test-case">test case</a> too. A (normally) automated <a class="reference internal" href="#test-program">test
321 program</a> run all the <a class="reference internal" href="#test-suite">test suites</a> and print some stats. It fails
322 (returns non-zero) if any <a class="reference internal" href="#test-suite">test suite</a> fails.</p>
323 </div>
324 <div class="contents topic" id="contents">
325 <p class="topic-title first">Contents</p>
326 <ul class="auto-toc simple">
327 <li><a class="reference internal" href="#installation" id="id9">1.&nbsp;&nbsp;&nbsp;Installation</a></li>
328 <li><a class="reference internal" href="#quick-sample" id="id10">2.&nbsp;&nbsp;&nbsp;Quick Sample</a><ul class="auto-toc">
329 <li><a class="reference internal" href="#factorial-c" id="id11">2.1.&nbsp;&nbsp;&nbsp;factorial.c</a></li>
330 <li><a class="reference internal" href="#factorial-test-c" id="id12">2.2.&nbsp;&nbsp;&nbsp;factorial_test.c</a></li>
331 <li><a class="reference internal" href="#exception-test-cpp" id="id13">2.3.&nbsp;&nbsp;&nbsp;exception_test.cpp</a></li>
332 </ul>
333 </li>
334 <li><a class="reference internal" href="#concepts" id="id14">3.&nbsp;&nbsp;&nbsp;Concepts</a><ul class="auto-toc">
335 <li><a class="reference internal" href="#test-program" id="id15">3.1.&nbsp;&nbsp;&nbsp;Test Program</a></li>
336 <li><a class="reference internal" href="#test-suite" id="id16">3.2.&nbsp;&nbsp;&nbsp;Test Suite</a></li>
337 <li><a class="reference internal" href="#test-case" id="id17">3.3.&nbsp;&nbsp;&nbsp;Test Case</a></li>
338 <li><a class="reference internal" href="#checks" id="id18">3.4.&nbsp;&nbsp;&nbsp;Checks</a></li>
339 <li><a class="reference internal" href="#initialization" id="id19">3.5.&nbsp;&nbsp;&nbsp;Initialization</a></li>
340 <li><a class="reference internal" href="#termination" id="id20">3.6.&nbsp;&nbsp;&nbsp;Termination</a></li>
341 </ul>
342 </li>
343 <li><a class="reference internal" href="#c-support" id="id21">4.&nbsp;&nbsp;&nbsp;C++ Support</a></li>
344 <li><a class="reference internal" href="#implementations" id="id22">5.&nbsp;&nbsp;&nbsp;Implementations</a><ul class="auto-toc">
345 <li><a class="reference internal" href="#static-implementations" id="id23">5.1.&nbsp;&nbsp;&nbsp;Static Implementations</a><ul class="auto-toc">
346 <li><a class="reference internal" href="#c-implementation" id="id24">5.1.1.&nbsp;&nbsp;&nbsp;C implementation</a><ul class="auto-toc">
347 <li><a class="reference internal" href="#mkmutest-invocation" id="id25">5.1.1.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mkmutest</span></tt> Invocation</a></li>
348 <li><a class="reference internal" href="#test-program-invocation" id="id26">5.1.1.2.&nbsp;&nbsp;&nbsp;Test Program Invocation</a></li>
349 <li><a class="reference internal" href="#dependencies" id="id27">5.1.1.3.&nbsp;&nbsp;&nbsp;Dependencies</a></li>
350 </ul>
351 </li>
352 </ul>
353 </li>
354 <li><a class="reference internal" href="#dynamic-implementations" id="id28">5.2.&nbsp;&nbsp;&nbsp;Dynamic Implementations</a><ul class="auto-toc">
355 <li><a class="reference internal" href="#python-implementation" id="id29">5.2.1.&nbsp;&nbsp;&nbsp;Python implementation</a><ul class="auto-toc">
356 <li><a class="reference internal" href="#mutest-invocation" id="id30">5.2.1.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mutest</span></tt> Invocation</a></li>
357 <li><a class="reference internal" href="#id8" id="id31">5.2.1.2.&nbsp;&nbsp;&nbsp;Dependencies</a></li>
358 </ul>
359 </li>
360 </ul>
361 </li>
362 </ul>
363 </li>
364 <li><a class="reference internal" href="#reference" id="id32">6.&nbsp;&nbsp;&nbsp;Reference</a><ul class="auto-toc">
365 <li><a class="reference internal" href="#mu-check" id="id33">6.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_check()</span></tt></a></li>
366 <li><a class="reference internal" href="#mu-ensure" id="id34">6.2.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_ensure()</span></tt></a></li>
367 <li><a class="reference internal" href="#mu-echeck" id="id35">6.3.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_echeck()</span></tt></a></li>
368 <li><a class="reference internal" href="#mu-eensure" id="id36">6.4.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_eensure()</span></tt></a></li>
369 </ul>
370 </li>
371 <li><a class="reference internal" href="#about" id="id37">7.&nbsp;&nbsp;&nbsp;About</a></li>
372 </ul>
373 </div>
374 <div class="section" id="installation">
375 <h1><a class="toc-backref" href="#id9">1.&nbsp;&nbsp;&nbsp;Installation</a></h1>
376 <p>Download the <a class="reference external" href="https://llucax.com/proj/mutest/releases/mutest.tar.gz">latest distribution tarball</a> and uncompress it.</p>
377 <p>You can also download any release from the <a class="reference external" href="https://llucax.com/proj/mutest/releases/">releases directory</a> or get it
378 using <a class="reference external" href="https://git.or.cz/">Git</a> directly from the <a class="reference external" href="http://git.llucax.com/w/software/mutest.git">Git repository</a>.</p>
379 <p>You can get <a class="reference external" href="https://llucax.com/proj/mutest/manual.html">this manual</a> too, or a <a class="reference external" href="http://llucax.com/proj/mutest/manual.pdf">PDF version</a> of it.</p>
380 <p>To actually install <em>mutest</em> run:</p>
381 <pre class="literal-block">
382 $ make install
383 </pre>
384 <p>Default installation path is <tt class="docutils literal"><span class="pre">/usr/local</span></tt> (because of that, you'll probably
385 need superuser privileges to install to the default location). You can override
386 that by passing the <tt class="docutils literal"><span class="pre">prefix</span></tt> make variable, for example:</p>
387 <pre class="literal-block">
388 $ make prefix=/opt/mutest install
389 </pre>
390 <p>If you want to install just the docs, you can do:</p>
391 <pre class="literal-block">
392 $ make install-doc
393 </pre>
394 <p>Or even <tt class="docutils literal"><span class="pre">install-readme</span></tt>, <tt class="docutils literal"><span class="pre">install-html</span></tt> or <tt class="docutils literal"><span class="pre">install-pdf</span></tt> if you are too
395 picky.</p>
396 <p>If you want to install just one particular <a class="reference internal" href="#implementations">implementation</a>, to can use the
397 <tt class="docutils literal"><span class="pre">install-c</span></tt> and <tt class="docutils literal"><span class="pre">install-py</span></tt> targets.</p>
398 </div>
399 <div class="section" id="quick-sample">
400 <h1><a class="toc-backref" href="#id10">2.&nbsp;&nbsp;&nbsp;Quick Sample</a></h1>
401 <p>You can find some samples in the <a class="reference external" href="https://git.llucax.com/w/software/mutest.git?a=tree;f=sample;h=d8ad4dd9c3428fef5963107c82ab6a5e34ec6e00;hb=HEAD">sample</a> directory.</p>
402 <p>This is an example taken from there. A simple <em>module</em> called <a class="reference internal" href="#factorial-c">factorial.c</a>
403 with its corresponding <a class="reference internal" href="#test-suite">test suite</a> (<a class="reference internal" href="#factorial-test-c">factorial_test.c</a>).</p>
404 <p>You can see some <a class="reference internal" href="#c-support">C++ support</a> in the <a class="reference internal" href="#exception-test-cpp">exception_test.cpp</a> <a class="reference internal" href="#test-suite">test suite</a>.</p>
405 <div class="section" id="factorial-c">
406 <h2><a class="toc-backref" href="#id11">2.1.&nbsp;&nbsp;&nbsp;factorial.c</a></h2>
407 <pre class="literal-block">
408 /*
409  * This file is part of mutest, a simple micro unit testing framework for C.
410  *
411  * mutest was written by Leandro Lucarella &lt;llucax&#64;gmail.com&gt; and is released
412  * under the BOLA license, please see the LICENSE file or visit:
413  * http://blitiri.com.ar/p/bola/
414  *
415  * This is an example module that calculates a factorial.
416  *
417  * Please, read the README file for more details.
418  */
419
420 unsigned factorial(unsigned x) {
421         if (x &lt;= 1)
422                 return 1;
423         return x * factorial(x-1);
424 }
425
426
427 </pre>
428 </div>
429 <div class="section" id="factorial-test-c">
430 <h2><a class="toc-backref" href="#id12">2.2.&nbsp;&nbsp;&nbsp;factorial_test.c</a></h2>
431 <pre class="literal-block">
432 /*
433  * This file is part of mutest, a simple micro unit testing framework for C.
434  *
435  * mutest was written by Leandro Lucarella &lt;llucax&#64;gmail.com&gt; and is released
436  * under the BOLA license, please see the LICENSE file or visit:
437  * http://blitiri.com.ar/p/bola/
438  *
439  * This is the factorial module test suite. Each (public) function starting
440  * with mu_test will be picked up by mkmutest as a test case.
441  *
442  * Please, read the README file for more details.
443  */
444
445 #include &quot;factorial.h&quot;
446
447 #include &quot;../mutest.h&quot;
448
449 void mu_test_factorial_zero() {
450         unsigned x = factorial(0);
451         mu_check(x == 1);
452 }
453
454 void mu_test_factorial_one() {
455         unsigned x = factorial(1);
456         /* this test is wrong on purpose, to see how it fails */
457         mu_check(x == 2);
458 }
459
460 void mu_test_factorial_positive() {
461         unsigned x = factorial(2);
462         /* this test is wrong on purpose, to see how it fails */
463         mu_check(x == 3);
464
465         x = factorial(3);
466         /* we don't want to continue if this fails, because the next result
467          * depends on this one. This one will succeed. */
468         mu_ensure(x == 6);
469
470         x = factorial(x);
471         mu_check(x == 720);
472
473         x = factorial(4);
474         mu_ensure(x == 6); /* same as before, but this one will fail. */
475
476         x = factorial(x-15); /* and this will never be executed */
477         mu_check(x == 362881); /* but if excecuted, will fail */
478 }
479
480
481 </pre>
482 </div>
483 <div class="section" id="exception-test-cpp">
484 <h2><a class="toc-backref" href="#id13">2.3.&nbsp;&nbsp;&nbsp;exception_test.cpp</a></h2>
485 <pre class="literal-block">
486 /*
487  * This file is part of mutest, a simple micro unit testing framework for C.
488  *
489  * mutest was written by Leandro Lucarella &lt;llucax&#64;gmail.com&gt; and is released
490  * under the BOLA license, please see the LICENSE file or visit:
491  * http://blitiri.com.ar/p/bola/
492  *
493  * This is a C++ module test suite. It shows how to use checks involving
494  * exceptions.
495  *
496  * Please, read the README file for more details.
497  */
498
499 #include &lt;stdexcept&gt; // std::out_of_range
500 #include &lt;vector&gt; // std::vector
501
502 #include &quot;../mutest.h&quot;
503
504 extern &quot;C&quot; {
505
506 void mu_test_exceptions() {
507         std::vector&lt;int&gt; v(1);
508         // ok
509         mu_check(v.at(0) == 0);
510         // throws! This fails
511         mu_check(v.at(1) == 0);
512         // ok, we expect the exception to be thrown, and it does
513         mu_echeck(std::out_of_range, v.at(1));
514         // fails! We expect this to throw, but it doesn't
515         mu_echeck(std::out_of_range, v.at(0));
516         // fails again, but this time the show is over (note the &quot;ensure&quot;)
517         mu_eensure(std::out_of_range, v.at(0));
518         // this will never be executed (it should fail if it is)
519         mu_check(v.empty());
520 }
521
522 } // extern &quot;C&quot;
523
524
525 </pre>
526 </div>
527 </div>
528 <div class="section" id="concepts">
529 <h1><a class="toc-backref" href="#id14">3.&nbsp;&nbsp;&nbsp;Concepts</a></h1>
530 <p><em>mutest</em> is about 4 simple concepts: <a class="reference internal" href="#test-program">test program</a>, <a class="reference internal" href="#test-suite">test suite</a>, <a class="reference internal" href="#test-case">test
531 case</a> and <a class="reference internal" href="#checks">checks</a>. Well, to be honest you probably will need <a class="reference internal" href="#test-suite">test suite</a>
532 <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a> too =)</p>
533 <div class="section" id="test-program">
534 <h2><a class="toc-backref" href="#id15">3.1.&nbsp;&nbsp;&nbsp;Test Program</a></h2>
535 <p>A <strong>test program</strong> is the higher level unit of <em>mutest</em>. The test program is
536 the one in charge of running all your tests. Probably one of the more important
537 features of <em>mutest</em> is that you are not supposed to bother about the test
538 program. So, different <a class="reference internal" href="#implementations">implementations</a> have different ways to tackle this.
539 Some need more or less interactions from your part, and each have their pros
540 and cons.</p>
541 <p>But this is all you need to know for now, for more details see how the test
542 program is implemented by your <a class="reference internal" href="#implementations">implementation</a> of choice.</p>
543 </div>
544 <div class="section" id="test-suite">
545 <h2><a class="toc-backref" href="#id16">3.2.&nbsp;&nbsp;&nbsp;Test Suite</a></h2>
546 <p>A <strong>test suite</strong> is the higher level unit of <em>mutest</em> that you should
547 care about =). Is not much more than a way to group <a class="reference internal" href="#test-case">test cases</a>. Code-wise,
548 a test suite is a C (or C++) module (or compilation unit). Not clear enough?
549 A unit test is an object file (could be a shared object depending on the
550 <a class="reference internal" href="#implementations">implementation</a>). This module should have one or more <a class="reference internal" href="#test-case">test cases</a> and it
551 could have any number (including zero) of <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a>
552 functions.</p>
553 <p>A test suite, is inspected by the <a class="reference internal" href="#test-program">test program</a> for <a class="reference internal" href="#test-case">test cases</a> and
554 <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a> functions, and run them.</p>
555 <p>A test suite fail if one or more <a class="reference internal" href="#test-case">test cases</a> fail, and it's skipped if one or
556 more <a class="reference internal" href="#initialization">initialization</a> functions fail (or, depending on the implementation, if
557 the test suite can't be loaded at all).</p>
558 </div>
559 <div class="section" id="test-case">
560 <h2><a class="toc-backref" href="#id17">3.3.&nbsp;&nbsp;&nbsp;Test Case</a></h2>
561 <p>A <strong>test case</strong> is just a plain function with a special signature and name.
562 A test case function name must start with <tt class="docutils literal"><span class="pre">mu_test</span></tt>, and take no arguments
563 and return nothing. For example:</p>
564 <pre class="literal-block">
565 void mu_test_something(void);
566 </pre>
567 <p>A test case (probably) only make sense if it has <a class="reference internal" href="#checks">checks</a>. A test case succeed
568 only if all its checks succeed too.</p>
569 <p>Test are executed in an <a class="reference internal" href="#implementations">implementation</a>-dependant order, but usually the
570 default order is alphabetical.</p>
571 </div>
572 <div class="section" id="checks">
573 <h2><a class="toc-backref" href="#id18">3.4.&nbsp;&nbsp;&nbsp;Checks</a></h2>
574 <p>Checks are assertions that a <a class="reference internal" href="#test-case">test case</a> must pass (a boolean expression that
575 must evaluate to <em>true</em>). There are 2 big flavors of checks: <strong>check</strong> and
576 <strong>ensure</strong>. <strong>check</strong> just print an error (and <em>mark</em> the <a class="reference internal" href="#test-case">test case</a> as
577 failed) and <strong>ensure</strong> halt the <a class="reference internal" href="#test-case">test case</a> execution, jumping to the next
578 one.</p>
579 <p>For better <a class="reference internal" href="#c-support">C++ support</a> there are check macros that assert that a specified
580 exception is thrown (instead of check for a boolean expression to evaluate to
581 <em>true</em>).</p>
582 <p>You can take a look at the <a class="reference internal" href="#reference">reference</a> to see the different flavors of check
583 macros in more detail.</p>
584 </div>
585 <div class="section" id="initialization">
586 <h2><a class="toc-backref" href="#id19">3.5.&nbsp;&nbsp;&nbsp;Initialization</a></h2>
587 <p>Sometimes you need to setup some environment shared between all the <a class="reference internal" href="#test-case">test
588 cases</a> in a <a class="reference internal" href="#test-suite">test suite</a>. You can use <strong>initialization functions</strong> for this.</p>
589 <p>An initialization function, like a <a class="reference internal" href="#test-case">test case</a>, is a plain C function with
590 a special name and signature. The name must start with <tt class="docutils literal"><span class="pre">mu_init</span></tt> and it must
591 take no arguments, and return an <em>error code</em> (<tt class="docutils literal"><span class="pre">0</span></tt> being success). For
592 example:</p>
593 <pre class="literal-block">
594 int mu_init_something(void);
595 </pre>
596 <p>All initialization functions are executed before any <a class="reference internal" href="#test-case">test case</a>, in an
597 <a class="reference internal" href="#implementations">implementation</a>-dependant order, and if one of them fail (returns non-zero),
598 the whole <a class="reference internal" href="#test-suite">test suite</a> is skipped immediately.</p>
599 </div>
600 <div class="section" id="termination">
601 <h2><a class="toc-backref" href="#id20">3.6.&nbsp;&nbsp;&nbsp;Termination</a></h2>
602 <p><strong>Termination functions</strong> are just like <a class="reference internal" href="#initialization">initialization</a> functions, but they're
603 executed <strong>after</strong> the <a class="reference internal" href="#test-case">test cases</a>, their names start with <tt class="docutils literal"><span class="pre">mu_term</span></tt> and
604 they return nothing. For example:</p>
605 <pre class="literal-block">
606 void mu_term_something(void);
607 </pre>
608 </div>
609 </div>
610 <div class="section" id="c-support">
611 <h1><a class="toc-backref" href="#id21">4.&nbsp;&nbsp;&nbsp;C++ Support</a></h1>
612 <p>You can use <em>mutest</em> with C++, the only care you must take is that, because of
613 C++ <a class="reference external" href="http://en.wikipedia.org/wiki/Name_mangling">name mangling</a> (and <em>mutest</em> relaying on function names), you must
614 declare your <a class="reference internal" href="#test-case">test cases</a> and <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a> functions as
615 <tt class="docutils literal"><span class="pre">extern</span> <span class="pre">&quot;C&quot;</span></tt> (see <a class="reference internal" href="#exception-test-cpp">exception_test.cpp</a> for an example).</p>
616 <p><a class="reference internal" href="#checks">Checks</a> become <em>exception-safe</em> when using <em>mutest</em> with a C++ compiler, and
617 2 extra <a class="reference internal" href="#checks">checks</a> designed for C++ get defined (<a class="reference internal" href="#mu-echeck">mu_echeck()</a> and
618 <a class="reference internal" href="#mu-eensure">mu_eensure()</a>). They assert that an expression throws a particular exception.</p>
619 </div>
620 <div class="section" id="implementations">
621 <h1><a class="toc-backref" href="#id22">5.&nbsp;&nbsp;&nbsp;Implementations</a></h1>
622 <p>There are 2 big groups of possible implementations that I can think
623 of: <em>static</em> and <em>dynamic</em>.</p>
624 <p><em>mutest</em> comes with one implementation of each group.</p>
625 <div class="section" id="static-implementations">
626 <h2><a class="toc-backref" href="#id23">5.1.&nbsp;&nbsp;&nbsp;Static Implementations</a></h2>
627 <p>Static implementations can be only written in C/C++ (or other language that is
628 link-compatible with C, like the <a class="reference external" href="http://www.digitalmars.com/d/">D Programming Language</a>, but since one of
629 the main goals of <em>mutest</em> is avoid unnecessary dependencies, you probably
630 don't want to depend on an extra language/compiler to run your tests =).</p>
631 <p>The main advantage is better debugging support, because you can run the <a class="reference internal" href="#test-program">test
632 program</a> in a standard debugger and see what happens with <a class="reference internal" href="#test-case">test cases</a> very
633 naturally.</p>
634 <p>The main disadvantage is, the <a class="reference internal" href="#test-suite">test suites</a> must be figured out in
635 <em>compile-time</em>, usually using some kind of code generation (if you want to
636 avoid writing repetitive code yourself). There's also a limitation in the <a class="reference internal" href="#test-case">test
637 case</a>, <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a> functions names: they should be unique
638 for all the <a class="reference internal" href="#test-program">test program</a>.</p>
639 <div class="section" id="c-implementation">
640 <h3><a class="toc-backref" href="#id24">5.1.1.&nbsp;&nbsp;&nbsp;C implementation</a></h3>
641 <p><em>mutest</em> comes with a C static implementation. Only 3 files are needed:
642 <tt class="docutils literal"><span class="pre">mutest.c</span></tt> (the <em>user-independent</em> part of the <a class="reference internal" href="#test-program">test program</a>), <tt class="docutils literal"><span class="pre">mkmutest</span></tt>
643 (a bash script for generating the <em>user-dependent</em> part of the <a class="reference internal" href="#test-program">test program</a>)
644 and <tt class="docutils literal"><span class="pre">mutest.h</span></tt> (the header file that <a class="reference internal" href="#test-suite">test suites</a> should include).</p>
645 <p>You can copy this 3 files to your project or install them at system-level and
646 use them globally.</p>
647 <p>The procedure is simple, You should compile you <a class="reference internal" href="#test-suite">test suites</a>, <tt class="docutils literal"><span class="pre">mutest.c</span></tt>
648 and the generated output of <tt class="docutils literal"><span class="pre">mkmutest</span></tt> as object files and link them
649 together.</p>
650 <p>For example:</p>
651 <pre class="literal-block">
652 $ cc -c -o mutest.o mutest.c
653 $ cc -c -o test1.o test1.c
654 $ cc -c -o test2.o test2.c
655 $ mkmutest mutest.h test1.o test2.o | cc -xc -c -o runmutest.o -
656 $ cc -o testprg mutest.o test1.o test2.o runmutest.o
657 </pre>
658 <p>Then you can run the <a class="reference internal" href="#test-program">test program</a> invoking it with no arguments:</p>
659 <pre class="literal-block">
660 $ ./testprg
661 </pre>
662 <div class="section" id="mkmutest-invocation">
663 <h4><a class="toc-backref" href="#id25">5.1.1.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mkmutest</span></tt> Invocation</a></h4>
664 <p>This small script take 1 mandatory positional argument: the path to the
665 <tt class="docutils literal"><span class="pre">mutest.h</span></tt> file. All remaining positional arguments should be object files
666 representing <a class="reference internal" href="#test-suite">test suites</a>.</p>
667 </div>
668 <div class="section" id="test-program-invocation">
669 <h4><a class="toc-backref" href="#id26">5.1.1.2.&nbsp;&nbsp;&nbsp;Test Program Invocation</a></h4>
670 <p>The test program can be invoked without arguments, but can take some extra
671 options:</p>
672 <dl class="docutils">
673 <dt><tt class="docutils literal"><span class="pre">-v</span></tt></dt>
674 <dd><p class="first">Be verbose. This is accumulative, when you add extra <tt class="docutils literal"><span class="pre">-v</span></tt> you will
675 get extra verbosity.</p>
676 <p class="last">By default, you just get failed <a class="reference internal" href="#checks">checks</a> printed. If you use a single
677 <tt class="docutils literal"><span class="pre">-v</span></tt>, a summary of failed/passed <a class="reference internal" href="#test-suite">test suites</a>, <a class="reference internal" href="#test-case">test cases</a> and
678 <a class="reference internal" href="#checks">checks</a> will be printed. If an extra <tt class="docutils literal"><span class="pre">-v</span></tt> is used, you'll see the current
679 <a class="reference internal" href="#test-suite">test suite</a> being executed. Another <tt class="docutils literal"><span class="pre">-v</span></tt> and you'll get the current
680 <a class="reference internal" href="#test-case">test case</a>, and another one, and you'll get each <a class="reference internal" href="#checks">check</a>.</p>
681 </dd>
682 </dl>
683 </div>
684 <div class="section" id="dependencies">
685 <h4><a class="toc-backref" href="#id27">5.1.1.3.&nbsp;&nbsp;&nbsp;Dependencies</a></h4>
686 <p>Even when dependencies are kept minimal, there always be a few ;)</p>
687 <p>To use this implementation you just need:</p>
688 <ul class="simple">
689 <li>A C compiler (you already needed that, so...)</li>
690 <li>The <tt class="docutils literal"><span class="pre">nm</span></tt> program (from <a class="reference external" href="http://www.gnu.org/software/binutils/">GNU Binutils</a>, included in virtually any *NIX)</li>
691 <li>The <a class="reference external" href="http://www.gnu.org/software/bash/">GNU Bash</a> shell interpreter (also included in virtually any *NIX)</li>
692 </ul>
693 </div>
694 </div>
695 </div>
696 <div class="section" id="dynamic-implementations">
697 <h2><a class="toc-backref" href="#id28">5.2.&nbsp;&nbsp;&nbsp;Dynamic Implementations</a></h2>
698 <p>Dynamic implementations, on the other hand, can be written in any language that
699 can access to shared objects. The idea is to inspect a shared object for <a class="reference internal" href="#test-suite">test
700 suites</a> and run them, without requiring any information about <a class="reference internal" href="#test-suite">test suites</a>
701 at compile time.</p>
702 <p>There are several advantages in this kind of implementations. The dynamic
703 nature let you completely separate the <a class="reference internal" href="#test-program">test program</a> from the user-written
704 <a class="reference internal" href="#test-suite">test suites</a> and you can choose at <em>run-time</em> what <a class="reference internal" href="#test-suite">test suites</a> to execute
705 by just selecting the correct shared objects. Also, <a class="reference internal" href="#test-case">test case</a>,
706 <a class="reference internal" href="#initialization">initialization</a> and <a class="reference internal" href="#termination">termination</a> functions names only have to be unique in the
707 scope of the <a class="reference internal" href="#test-suite">test suites</a>, because <a class="reference internal" href="#test-suite">test suites</a> are completely isolated in
708 separate shared objects.</p>
709 <p>But everything comes at a price, and the higher price to pay is
710 <em>debuggability</em>. It's a little harder to plug a debugger to a shared object.</p>
711 <div class="section" id="python-implementation">
712 <h3><a class="toc-backref" href="#id29">5.2.1.&nbsp;&nbsp;&nbsp;Python implementation</a></h3>
713 <p>This implementation is much simpler and elegant than the <a class="reference internal" href="#c-implementation">C implementation</a>.
714 Only 2 files are needed: <tt class="docutils literal"><span class="pre">mutest</span></tt> (<a class="reference internal" href="#test-program">test program</a> written in <a class="reference external" href="http://www.python.org/">Python</a> using
715 <a class="reference external" href="http://docs.python.org/library/ctypes.html">ctypes</a> module to access the shared object symbols) and <tt class="docutils literal"><span class="pre">mutest.h</span></tt> (the
716 header file that <a class="reference internal" href="#test-suite">test suites</a> should include).</p>
717 <p>Since both implementations provided by <em>mutest</em> share the same <tt class="docutils literal"><span class="pre">mutest.h</span></tt>,
718 you should define the <tt class="docutils literal"><span class="pre">MUTEST_PY</span></tt> macro when compiling the <a class="reference internal" href="#test-suite">test suites</a> if
719 you will run them using this implementation.</p>
720 <p>As with the <a class="reference internal" href="#c-implementation">C implementation</a>, you can copy this 2 files to your project or
721 install them at system-level and use them globally.</p>
722 <p>The procedure is even simpler than the <a class="reference internal" href="#c-implementation">C implementation</a>: compile and link
723 you <a class="reference internal" href="#test-suite">test suites</a> as shared objects and then run the <tt class="docutils literal"><span class="pre">mutest</span></tt> program
724 passing the shared objects as arguments. For example:</p>
725 <pre class="literal-block">
726 $ cc -c -fPIC -DMUTEST_PY -o test1.o test1.c
727 $ cc -shared -o test1.so test1.o
728 $ cc -c -fPIC -DMUTEST_PY -o test2.o test2.c
729 $ cc -shared -o test2.so test2.o
730 $ mutest test1.so test2.so
731 </pre>
732 <p>That's it.</p>
733 <div class="section" id="mutest-invocation">
734 <h4><a class="toc-backref" href="#id30">5.2.1.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mutest</span></tt> Invocation</a></h4>
735 <p><tt class="docutils literal"><span class="pre">mutest</span></tt> program takes <a class="reference internal" href="#test-suite">test suites</a> shared objects to run as positional
736 arguments. It accepts the same options as the <a class="reference internal" href="#test-program-invocation">C implementation's test
737 program</a> and some extra options are accepted too:</p>
738 <dl class="docutils">
739 <dt><tt class="docutils literal"><span class="pre">--verbose</span></tt></dt>
740 <dd>Alias for <tt class="docutils literal"><span class="pre">-v</span></tt>.</dd>
741 <dt><tt class="docutils literal"><span class="pre">-q</span></tt>, <tt class="docutils literal"><span class="pre">--quiet</span></tt></dt>
742 <dd>Be quiet (no output is shown at all).</dd>
743 <dt><tt class="docutils literal"><span class="pre">-s</span></tt>, <tt class="docutils literal"><span class="pre">--search</span></tt></dt>
744 <dd>Search for <a class="reference internal" href="#test-suite">test suites</a> (*.so) in the current directory and add them
745 to the list of <a class="reference internal" href="#test-suite">test suites</a> to run.</dd>
746 <dt><tt class="docutils literal"><span class="pre">-h</span></tt>, <tt class="docutils literal"><span class="pre">--help</span></tt></dt>
747 <dd>Show a help message and exit.</dd>
748 </dl>
749 </div>
750 <div class="section" id="id8">
751 <h4><a class="toc-backref" href="#id31">5.2.1.2.&nbsp;&nbsp;&nbsp;Dependencies</a></h4>
752 <p>As with the <a class="reference internal" href="#c-implementation">C implementation</a>, some minor dependencies are needed:</p>
753 <ul class="simple">
754 <li><a class="reference external" href="http://www.python.org/">Python</a> (2.5 or later)</li>
755 <li>The <tt class="docutils literal"><span class="pre">nm</span></tt> program (from <a class="reference external" href="http://www.gnu.org/software/binutils/">GNU Binutils</a>, included in virtually any *NIX)</li>
756 </ul>
757 <p>You will need a C compiler for building the <a class="reference internal" href="#test-suite">test suites</a> too, but technically
758 is not needed by <em>mutest</em> itself ;)</p>
759 </div>
760 </div>
761 </div>
762 </div>
763 <div class="section" id="reference">
764 <h1><a class="toc-backref" href="#id32">6.&nbsp;&nbsp;&nbsp;Reference</a></h1>
765 <div class="section" id="mu-check">
766 <h2><a class="toc-backref" href="#id33">6.1.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_check()</span></tt></a></h2>
767 <dl class="docutils">
768 <dt>Synopsis</dt>
769 <dd><tt class="docutils literal"><span class="pre">mu_check(expression)</span></tt></dd>
770 <dt>Description</dt>
771 <dd>Check that the <tt class="docutils literal"><span class="pre">expression</span></tt> evaluates to <em>true</em>. Continue with the
772 <a class="reference internal" href="#test-case">test case</a> if fail.</dd>
773 <dt>Availability</dt>
774 <dd>Always</dd>
775 <dt>Example</dt>
776 <dd><pre class="first last literal-block">
777 void mu_test(void)
778 {
779     mu_check(5 == 4); /* fail */
780     mu_check(5 == 5); /* excecuted, pass */
781 }
782 </pre>
783 </dd>
784 </dl>
785 </div>
786 <div class="section" id="mu-ensure">
787 <h2><a class="toc-backref" href="#id34">6.2.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_ensure()</span></tt></a></h2>
788 <dl class="docutils">
789 <dt>Synopsis</dt>
790 <dd><tt class="docutils literal"><span class="pre">mu_ensure(expression)</span></tt></dd>
791 <dt>Description</dt>
792 <dd>Check that the <tt class="docutils literal"><span class="pre">expression</span></tt> evaluates to <em>true</em>. Interrupt the <a class="reference internal" href="#test-case">test
793 case</a> if fail.</dd>
794 <dt>Availability</dt>
795 <dd>Always</dd>
796 <dt>Example</dt>
797 <dd><pre class="first last literal-block">
798 void mu_test(void)
799 {
800     mu_ensure(5 == 4); /* fail */
801     mu_check(5 == 5); /* not excecuted */
802 }
803 </pre>
804 </dd>
805 </dl>
806 </div>
807 <div class="section" id="mu-echeck">
808 <h2><a class="toc-backref" href="#id35">6.3.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_echeck()</span></tt></a></h2>
809 <dl class="docutils">
810 <dt>Synopsis</dt>
811 <dd><tt class="docutils literal"><span class="pre">mu_echeck(class,</span> <span class="pre">expression)</span></tt></dd>
812 <dt>Description</dt>
813 <dd>Check that the <tt class="docutils literal"><span class="pre">expression</span></tt> throws a specific exception <tt class="docutils literal"><span class="pre">class</span></tt> (or
814 subclass). Continue with the <a class="reference internal" href="#test-case">test case</a> if fail.</dd>
815 <dt>Availability</dt>
816 <dd>C++ only</dd>
817 <dt>Example</dt>
818 <dd><pre class="first last literal-block">
819 #include &lt;stdexcept&gt;
820
821 extern &quot;C&quot;
822 {
823     void mu_test(void)
824     {
825         mu_echeck(std::exception, true); /* fail */
826         mu_echeck(std::exception,
827                 throw std::runtime_error(&quot;!&quot;)); /* excecuted, pass */
828     }
829 }
830 </pre>
831 </dd>
832 </dl>
833 </div>
834 <div class="section" id="mu-eensure">
835 <h2><a class="toc-backref" href="#id36">6.4.&nbsp;&nbsp;&nbsp;<tt class="docutils literal"><span class="pre">mu_eensure()</span></tt></a></h2>
836 <dl class="docutils">
837 <dt>Synopsis</dt>
838 <dd><tt class="docutils literal"><span class="pre">mu_eensure(class,</span> <span class="pre">expression)</span></tt></dd>
839 <dt>Description</dt>
840 <dd>Check that the <tt class="docutils literal"><span class="pre">expression</span></tt> throws a specific exception <tt class="docutils literal"><span class="pre">class</span></tt> (or
841 subclass). Interrupt the <a class="reference internal" href="#test-case">test case</a> if fail.</dd>
842 <dt>Availability</dt>
843 <dd>C++ only</dd>
844 <dt>Example</dt>
845 <dd><pre class="first last literal-block">
846 #include &lt;stdexcept&gt;
847
848 extern &quot;C&quot;
849 {
850     void mu_test(void)
851     {
852         mu_eensure(std::exception, true); /* fail */
853         mu_echeck(std::exception,
854                 throw std::runtime_error(&quot;!&quot;)); /* not excecuted */
855     }
856 }
857 </pre>
858 </dd>
859 </dl>
860 </div>
861 </div>
862 <div class="section" id="about">
863 <h1><a class="toc-backref" href="#id37">7.&nbsp;&nbsp;&nbsp;About</a></h1>
864 <p>This manual was written using <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>.</p>
865 <!-- Use section numbers -->
866 <!-- Internal Links (aliases): -->
867 <!-- External Links: -->
868 <!-- Substitutions: -->
869 <!-- vim: set filetype=rst expandtab shiftwidth=4 softtabstop=4 : -->
870 </div>
871 </div>
872 </body>
873 </html>