]> git.llucax.com Git - software/mutest.git/blob - README
Add documentation
[software/mutest.git] / README
1
2 ======================================================
3 |mutest| - A simple micro unit testing framework for C
4 ======================================================
5
6 :Author: Leandro Lucarella
7 :Contact: llucax@gmail.com
8 :Version: 1.0
9 :Date: |date|
10 :Copyright: Leandro Lucarella (2008), released under the BOLA_ license
11 :Abstract: |mutest| is a micro `unit testing`_ framework for C (with some
12     `C++ support`_). It's mostly an idea (it even comes with
13     2 implementations_ of the idea!) with the goal of being easy to use
14     (just write your `test cases`_ grouped in `test suites`_ and you're
15     set) and so small and simple that you don't mind to copy the files to
16     your project and just use it (i.e., no dependencies).
17
18     The idea is simple: a source file is a `test suite`_, a function is
19     a `test case`_ (special functions can be used for `test suite`_
20     initialization_ and termination_), which can can have several checks_.
21     Checks_ comes in 2 flavors, one that only prints an error, and one that
22     terminates the current `test case`_ too. A (normally) automated `test
23     program`_ run all the `test suites`_ and print some stats. It fails
24     (returns non-zero) if any `test suite`_ fails.
25
26
27 .. contents::
28     :backlinks: entry
29
30
31 Installation
32 ============
33
34 Download the `latest distribution tarball`__ and uncompress it.
35
36 __ http://proj.llucax.com.ar/home/mutest/releases/mutest.tar.gz
37
38 You can also download any release from the `releases directory`__ or get it
39 using Git_ directly from the `Git repository`__.
40
41 __ http://proj.llucax.com.ar/home/mutest/releases/
42 __ http://git.llucax.com.ar/w/software/mutest.git
43
44 You can get `this manual`__ too, or a `PDF version`__ of it.
45
46 __ http://proj.llucax.com.ar/home/mutest/manual.html
47 __ http://proj.llucax.com.ar/home/mutest/manual.pdf
48
49 To actually install |mutest| run::
50
51     $ make install
52
53 Default installation path is ``/usr/local`` (because of that, you'll probably
54 need superuser privileges to install to the default location). You can override
55 that by passing the ``prefix`` make variable, for example::
56
57     $ make prefix=/opt/mutest install
58
59 If you want to install just the docs, you can do::
60
61     $ make install-doc
62
63 Or even ``install-readme``, ``install-html`` or ``install-pdf`` if you are too
64 picky.
65
66 If you want to install just one particular implementation_, to can use the
67 ``install-c`` and ``install-py`` targets.
68
69
70 Quick Sample
71 ============
72
73 You can find some samples in the sample__ directory.
74
75 __ http://git.llucax.com.ar/w/software/mutest.git?a=tree;f=sample;h=d8ad4dd9c3428fef5963107c82ab6a5e34ec6e00;hb=HEAD
76
77 This is an example taken from there. A simple *module* called `factorial.c`_
78 with its corresponding `test suite`_ (`factorial_test.c`_).
79
80 You can see some `C++ support`_ in the `exception_test.cpp`_ `test suite`_.
81
82 factorial.c
83 -----------
84
85 .. include:: sample/factorial.c
86     :literal:
87
88 factorial_test.c
89 ----------------
90
91 .. include:: sample/factorial_test.c
92     :literal:
93
94 exception_test.cpp
95 ------------------
96
97 .. include:: sample/exception_test.cpp
98     :literal:
99
100
101 Concepts
102 ========
103
104 |mutest| is about 4 simple concepts: `test program`_, `test suite`_, `test
105 case`_ and checks_. Well, to be honest you probably will need `test suite`_
106 initialization_ and termination_ too =)
107
108
109 Test Program
110 ------------
111
112 A **test program** is the higher level unit of |mutest|. The test program is
113 the one in charge of running all your tests. Probably one of the more important
114 features of |mutest| is that you are not supposed to bother about the test
115 program. So, different implementations_ have different ways to tackle this.
116 Some need more or less interactions from your part, and each have their pros
117 and cons.
118
119 But this is all you need to know for now, for more details see how the test
120 program is implemented by your implementation_ of choice.
121
122
123 Test Suite
124 ----------
125
126 A **test suite** is the higher level unit of |mutest| that you should
127 care about =). Is not much more than a way to group `test cases`_. Code-wise,
128 a test suite is a C (or C++) module (or compilation unit). Not clear enough?
129 A unit test is an object file (could be a shared object depending on the
130 implementation_). This module should have one or more `test cases`_ and it
131 could have any number (including zero) of initialization_ and termination_
132 functions.
133
134 A test suite, is inspected by the `test program`_ for `test cases`_ and
135 initialization_ and termination_ functions, and run them.
136
137 A test suite fail if one or more `test cases`_ fail, and it's skipped if one or
138 more initialization_ functions fail (or, depending on the implementation, if
139 the test suite can't be loaded at all).
140
141
142 Test Case
143 ---------
144
145 A **test case** is just a plain function with a special signature and name.
146 A test case function name must start with ``mu_test``, and take no arguments
147 and return nothing. For example::
148
149     void mu_test_something(void);
150
151 A test case (probably) only make sense if it has checks_. A test case succeed
152 only if all its checks succeed too.
153
154 Test are executed in an implementation_-dependant order, but usually the
155 default order is alphabetical.
156
157
158 Checks
159 ------
160
161 Checks are assertions that a `test case`_ must pass (a boolean expression that
162 must evaluate to *true*). There are 2 big flavors of checks: **check** and
163 **ensure**. **check** just print an error (and *mark* the `test case`_ as
164 failed) and **ensure** halt the `test case`_ execution, jumping to the next
165 one.
166
167 For better `C++ support`_ there are check macros that assert that a specified
168 exception is thrown (instead of check for a boolean expression to evaluate to
169 *true*).
170
171 You can take a look at the reference_ to see the different flavors of check
172 macros in more detail.
173
174
175 Initialization
176 --------------
177
178 Sometimes you need to setup some environment shared between all the `test
179 cases`_ in a `test suite`_. You can use **initialization functions** for this.
180
181 An initialization function, like a `test case`_, is a plain C function with
182 a special name and signature. The name must start with ``mu_init`` and it must
183 take no arguments, and return an *error code* (``0`` being success). For
184 example::
185
186     int mu_init_something(void);
187
188 All initialization functions are executed before any `test case`_, in an
189 implementation_-dependant order, and if one of them fail (returns non-zero),
190 the whole `test suite`_ is skipped immediately.
191
192
193 Termination
194 -----------
195
196 **Termination functions** are just like initialization_ functions, but they're
197 executed **after** the `test cases`_, their names start with ``mu_term`` and
198 they return nothing. For example::
199
200     void mu_term_something(void);
201
202
203 C++ Support
204 ===========
205
206 You can use |mutest| with C++, the only care you must take is that, because of
207 C++ `name mangling`_ (and |mutest| relaying on function names), you must
208 declare your `test cases`_ and initialization_ and termination_ functions as
209 ``extern "C"`` (see `exception_test.cpp`_ for an example).
210
211 Checks_ become *exception-safe* when using |mutest| with a C++ compiler, and
212 2 extra checks_ designed for C++ get defined (`mu_echeck()`_ and
213 `mu_eensure()`_). They assert that an expression throws a particular exception.
214
215
216 Implementations
217 ===============
218
219 There are 2 big groups of possible implementations that I can think
220 of: *static* and *dynamic*.
221
222 |mutest| comes with one implementation of each group.
223
224
225 Static Implementations
226 ----------------------
227
228 Static implementations can be only written in C/C++ (or other language that is
229 link-compatible with C, like the `D Programming Language`_, but since one of
230 the main goals of |mutest| is avoid unnecessary dependencies, you probably
231 don't want to depend on an extra language/compiler to run your tests =).
232
233 The main advantage is better debugging support, because you can run the `test
234 program`_ in a standard debugger and see what happens with `test cases`_ very
235 naturally.
236
237 The main disadvantage is, the `test suites`_ must be figured out in
238 *compile-time*, usually using some kind of code generation (if you want to
239 avoid writing repetitive code yourself). There's also a limitation in the `test
240 case`_, initialization_ and termination_ functions names: they should be unique
241 for all the `test program`_.
242
243
244 C implementation
245 ~~~~~~~~~~~~~~~~
246
247 |mutest| comes with a C static implementation. Only 3 files are needed:
248 ``mutest.c`` (the *user-independent* part of the `test program`_), ``mkmutest``
249 (a bash script for generating the *user-dependent* part of the `test program`_)
250 and ``mutest.h`` (the header file that `test suites`_ should include).
251
252 You can copy this 3 files to your project or install them at system-level and
253 use them globally.
254
255 The procedure is simple, You should compile you `test suites`_, ``mutest.c``
256 and the generated output of ``mkmutest`` as object files and link them
257 together.
258
259 For example::
260
261     $ cc -c -o mutest.o mutest.c
262     $ cc -c -o test1.o test1.c
263     $ cc -c -o test2.o test2.c
264     $ mkmutest mutest.h test1.o test2.o | cc -xc -c -o runmutest.o -
265     $ cc -o testprg mutest.o test1.o test2.o runmutest.o
266
267 Then you can run the `test program`_ invoking it with no arguments::
268
269     $ ./testprg
270
271
272 ``mkmutest`` Invocation
273 """""""""""""""""""""""
274
275 This small script take 1 mandatory positional argument: the path to the
276 ``mutest.h`` file. All remaining positional arguments should be object files
277 representing `test suites`_.
278
279
280 Test Program Invocation
281 """""""""""""""""""""""
282
283 The test program can be invoked without arguments, but can take some extra
284 options:
285
286 ``-v``
287     Be verbose. This is accumulative, when you add extra ``-v`` you will
288     get extra verbosity.
289
290     By default, you just get failed checks_ printed. If you use a single
291     ``-v``, a summary of failed/passed `test suites`_, `test cases`_ and
292     checks_ will be printed. If an extra ``-v`` is used, you'll see the current
293     `test suite`_ being executed. Another ``-v`` and you'll get the current
294     `test case`_, and another one, and you'll get each check_.
295
296
297 Dependencies
298 """"""""""""
299
300 Even when dependencies are kept minimal, there always be a few ;)
301
302 To use this implementation you just need:
303
304 * A C compiler (you already needed that, so...)
305 * The ``nm`` program (from `GNU Binutils`_, included in virtually any \*NIX)
306 * The `GNU Bash`_ shell interpreter (also included in virtually any \*NIX)
307
308
309 Dynamic Implementations
310 -----------------------
311
312 Dynamic implementations, on the other hand, can be written in any language that
313 can access to shared objects. The idea is to inspect a shared object for `test
314 suites`_ and run them, without requiring any information about `test suites`_
315 at compile time.
316
317 There are several advantages in this kind of implementations. The dynamic
318 nature let you completely separate the `test program`_ from the user-written
319 `test suites`_ and you can choose at *run-time* what `test suites`_ to execute
320 by just selecting the correct shared objects. Also, `test case`_,
321 initialization_ and termination_ functions names only have to be unique in the
322 scope of the `test suites`_, because `test suites`_ are completely isolated in
323 separate shared objects.
324
325 But everything comes at a price, and the higher price to pay is
326 *debuggability*. It's a little harder to plug a debugger to a shared object.
327
328
329 Python implementation
330 ~~~~~~~~~~~~~~~~~~~~~
331
332 This implementation is much simpler and elegant than the `C implementation`_.
333 Only 2 files are needed: ``mutest`` (`test program`_ written in Python_ using
334 ctypes_ module to access the shared object symbols) and ``mutest.h`` (the
335 header file that `test suites`_ should include).
336
337 Since both implementations provided by |mutest| share the same ``mutest.h``,
338 you should define the ``MUTEST_PY`` macro when compiling the `test suites`_ if
339 you will run them using this implementation.
340
341 As with the `C implementation`_, you can copy this 2 files to your project or
342 install them at system-level and use them globally.
343
344 The procedure is even simpler than the `C implementation`_: compile and link
345 you `test suites`_ as shared objects and then run the ``mutest`` program
346 passing the shared objects as arguments. For example::
347
348     $ cc -c -fPIC -DMUTEST_PY -o test1.o test1.c
349     $ cc -shared -o test1.so test1.o
350     $ cc -c -fPIC -DMUTEST_PY -o test2.o test2.c
351     $ cc -shared -o test2.so test2.o
352     $ mutest test1.so test2.so
353
354 That's it.
355
356 ``mutest`` Invocation
357 """""""""""""""""""""
358
359 ``mutest`` program takes `test suites`_ shared objects to run as positional
360 arguments. It accepts the same options as the `C implementation's test
361 program`__ and some extra options are accepted too:
362
363 ``--verbose``
364     Alias for ``-v``.
365
366 ``-q``, ``--quiet``
367     Be quiet (no output is shown at all).
368
369 ``-s``, ``--search``
370     Search for `test suites`_ (\*.so) in the current directory and add them
371     to the list of `test suites`_ to run.
372
373 ``-h``, ``--help``
374     Show a help message and exit.
375
376 __ `Test Program Invocation`_
377
378
379 Dependencies
380 """"""""""""
381
382 As with the `C implementation`_, some minor dependencies are needed:
383
384 * Python_ (2.5 or later)
385 * The ``nm`` program (from `GNU Binutils`_, included in virtually any \*NIX)
386
387 You will need a C compiler for building the `test suites`_ too, but technically
388 is not needed by |mutest| itself ;)
389
390
391 Reference
392 =========
393
394 ``mu_check()``
395 --------------
396
397 Synopsis
398     ``mu_check(expression)``
399
400 Description
401     Check that the ``expression`` evaluates to *true*. Continue with the
402     `test case`_ if fail.
403
404 Availability
405     Always
406
407 Example
408     ::
409
410         void mu_test(void)
411         {
412             mu_check(5 == 4); /* fail */
413             mu_check(5 == 5); /* excecuted, pass */
414         }
415
416
417 ``mu_ensure()``
418 ---------------
419
420 Synopsis
421     ``mu_ensure(expression)``
422
423 Description
424     Check that the ``expression`` evaluates to *true*. Interrupt the `test
425     case`_ if fail.
426
427 Availability
428     Always
429
430 Example
431     ::
432
433         void mu_test(void)
434         {
435             mu_ensure(5 == 4); /* fail */
436             mu_check(5 == 5); /* not excecuted */
437         }
438
439
440 ``mu_echeck()``
441 ---------------
442
443 Synopsis
444     ``mu_echeck(class, expression)``
445
446 Description
447     Check that the ``expression`` throws a specific exception ``class`` (or
448     subclass). Continue with the `test case`_ if fail.
449
450 Availability
451     C++ only
452
453 Example
454     ::
455
456         #include <stdexcept>
457
458         extern "C"
459         {
460             void mu_test(void)
461             {
462                 mu_echeck(std::exception, true); /* fail */
463                 mu_echeck(std::exception,
464                         throw std::runtime_error("!")); /* excecuted, pass */
465             }
466         }
467
468 ``mu_eensure()``
469 ----------------
470
471 Synopsis
472     ``mu_eensure(class, expression)``
473
474 Description
475     Check that the ``expression`` throws a specific exception ``class`` (or
476     subclass). Interrupt the `test case`_ if fail.
477
478 Availability
479     C++ only
480
481 Example
482     ::
483
484         #include <stdexcept>
485
486         extern "C"
487         {
488             void mu_test(void)
489             {
490                 mu_eensure(std::exception, true); /* fail */
491                 mu_echeck(std::exception,
492                         throw std::runtime_error("!")); /* not excecuted */
493             }
494         }
495
496
497 About
498 =====
499
500 This manual was written using reStructuredText_.
501
502 .. Use section numbers
503 .. sectnum::
504     :suffix: .
505
506 .. Internal Links (aliases):
507 .. _`test suites`: `test suite`_
508 .. _`test cases`: `test case`_
509 .. _check: checks_
510 .. _implementation: implementations_
511
512
513 .. External Links:
514 .. _BOLA: http://blitiri.com.ar/p/bola/
515 .. _`unit testing`: http://en.wikipedia.org/wiki/Unit_testing
516 .. _`name mangling`: http://en.wikipedia.org/wiki/Name_mangling
517 .. _`D Programming Language`: http://www.digitalmars.com/d/
518 .. _`GNU Binutils`: http://www.gnu.org/software/binutils/
519 .. _`GNU Bash`: http://www.gnu.org/software/bash/
520 .. _Python: http://www.python.org/
521 .. _ctypes: http://docs.python.org/library/ctypes.html
522 .. _reStructuredText: http://docutils.sourceforge.net/rst.html
523 .. _Git: http://git.or.cz/
524
525
526 .. Substitutions:
527 .. |mutest| replace:: *mutest*
528 .. |date| date::
529
530 .. vim: set filetype=rst expandtab shiftwidth=4 softtabstop=4 :
531