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