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>
9 ======================================================
10 |mutest| - A simple micro unit testing framework for C
11 ======================================================
13 :Author: Leandro Lucarella
14 :Contact: llucax@gmail.com
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).
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.
44 Download the `latest distribution tarball`__ and uncompress it.
46 __ http://proj.llucax.com.ar/home/mutest/releases/mutest.tar.gz
48 You can also download any release from the `releases directory`__ or get it
49 using Git_ directly from the `Git repository`__.
51 __ http://proj.llucax.com.ar/home/mutest/releases/
52 __ http://git.llucax.com.ar/w/software/mutest.git
54 You can get `this manual`__ too, or a `PDF version`__ of it.
56 __ http://proj.llucax.com.ar/home/mutest/manual.html
57 __ http://proj.llucax.com.ar/home/mutest/manual.pdf
59 To actually install |mutest| run::
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::
67 $ make prefix=/opt/mutest install
69 If you want to install just the docs, you can do::
73 Or even ``install-readme``, ``install-html`` or ``install-pdf`` if you are too
76 If you want to install just one particular implementation_, to can use the
77 ``install-c`` and ``install-py`` targets.
83 You can find some samples in the sample__ directory.
85 __ http://git.llucax.com.ar/w/software/mutest.git?a=tree;f=sample;h=d8ad4dd9c3428fef5963107c82ab6a5e34ec6e00;hb=HEAD
87 This is an example taken from there. A simple *module* called `factorial.c`_
88 with its corresponding `test suite`_ (`factorial_test.c`_).
90 You can see some `C++ support`_ in the `exception_test.cpp`_ `test suite`_.
95 .. include:: sample/factorial.c
101 .. include:: sample/factorial_test.c
107 .. include:: sample/exception_test.cpp
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 =)
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
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.
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_
144 A test suite, is inspected by the `test program`_ for `test cases`_ and
145 initialization_ and termination_ functions, and run them.
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).
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::
159 void mu_test_something(void);
161 A test case (probably) only make sense if it has checks_. A test case succeed
162 only if all its checks succeed too.
164 Test are executed in an implementation_-dependant order, but usually the
165 default order is alphabetical.
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
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
181 You can take a look at the reference_ to see the different flavors of check
182 macros in more detail.
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.
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
196 int mu_init_something(void);
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.
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::
210 void mu_term_something(void);
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).
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.
229 There are 2 big groups of possible implementations that I can think
230 of: *static* and *dynamic*.
232 |mutest| comes with one implementation of each group.
235 Static Implementations
236 ----------------------
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 =).
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
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`_.
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).
262 You can copy this 3 files to your project or install them at system-level and
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
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
277 Then you can run the `test program`_ invoking it with no arguments::
282 ``mkmutest`` Invocation
283 """""""""""""""""""""""
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`_.
290 Test Program Invocation
291 """""""""""""""""""""""
293 The test program can be invoked without arguments, but can take some extra
297 Be verbose. This is accumulative, when you add extra ``-v`` you will
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_.
310 Even when dependencies are kept minimal, there always be a few ;)
312 To use this implementation you just need:
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)
319 Dynamic Implementations
320 -----------------------
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`_
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.
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.
339 Python implementation
340 ~~~~~~~~~~~~~~~~~~~~~
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).
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.
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.
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::
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
366 ``mutest`` Invocation
367 """""""""""""""""""""
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:
377 Be quiet (no output is shown at all).
380 Search for `test suites`_ (\*.so) in the current directory and add them
381 to the list of `test suites`_ to run.
384 Show a help message and exit.
386 __ `Test Program Invocation`_
392 As with the `C implementation`_, some minor dependencies are needed:
394 * Python_ (2.5 or later)
395 * The ``nm`` program (from `GNU Binutils`_, included in virtually any \*NIX)
397 You will need a C compiler for building the `test suites`_ too, but technically
398 is not needed by |mutest| itself ;)
408 ``mu_check(expression)``
411 Check that the ``expression`` evaluates to *true*. Continue with the
412 `test case`_ if fail.
422 mu_check(5 == 4); /* fail */
423 mu_check(5 == 5); /* excecuted, pass */
431 ``mu_ensure(expression)``
434 Check that the ``expression`` evaluates to *true*. Interrupt the `test
445 mu_ensure(5 == 4); /* fail */
446 mu_check(5 == 5); /* not excecuted */
454 ``mu_echeck(class, expression)``
457 Check that the ``expression`` throws a specific exception ``class`` (or
458 subclass). Continue with the `test case`_ if fail.
472 mu_echeck(std::exception, true); /* fail */
473 mu_echeck(std::exception,
474 throw std::runtime_error("!")); /* excecuted, pass */
482 ``mu_eensure(class, expression)``
485 Check that the ``expression`` throws a specific exception ``class`` (or
486 subclass). Interrupt the `test case`_ if fail.
500 mu_eensure(std::exception, true); /* fail */
501 mu_echeck(std::exception,
502 throw std::runtime_error("!")); /* not excecuted */
510 This manual was written using reStructuredText_.
512 .. Use section numbers
516 .. Internal Links (aliases):
517 .. _`test suites`: `test suite`_
518 .. _`test cases`: `test case`_
520 .. _implementation: implementations_
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/
537 .. |mutest| replace:: *mutest*
540 .. vim: set filetype=rst expandtab shiftwidth=4 softtabstop=4 :