Sei sulla pagina 1di 2

01/02/2018 JTN002 - MinUnit -- a minimal unit testing framework for C

Jera Design : Tech Info : Jera Tech Notes

JTN002 - MinUnit -- a minimal unit testing


framework for C
Introduction
Source Code
Setting Up A Test Case
Example
Conclusion
License
Appendix: Why do {} while?

Introduction
Unit testing frameworks are quite popular in the object-oriented programming world. Frameworks like
JUnit (for Java), SUnit (for Smalltalk), and CppUnit (for C++) provide a rich set of functionality.
However, this rich set of functionality can be intimidating to someone who wants to do unit testing in a
more constrained environment, such as an embedded system written in C. But the important thing about
unit testing is the testing, not the framework. MinUnit is an extremely simple unit testing framework
written in C. It uses no memory allocation, so it should work fine under almost any circumstance,
including ROMable code.

Source Code
/* file: minunit.h */
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { char *message = test(); tests_run++; \
if (message) return message; } while (0)
extern int tests_run;

No, that's not a typo. It's just 3 lines of code (4 here because I wrapped a long line.)

Setting Up A Test Case


A MinUnit test case is just a function that returns 0 (null) if the tests pass. If the test fails, the function
should return a string describing the failing test. mu_assert is simply a macro that returns a string if the
expression passed to it is false. The mu_runtest macro calls another test case and returns if that test case
fails. That's all there is to it!

Example
The following example runs two tests, one that passes, one that fails.

/* file minunit_example.c */

#include <stdio.h>
#include "minunit.h"

int tests_run = 0;

int foo = 7;
int bar = 4;

http://www.jera.com/techinfo/jtns/jtn002.html#Appendix:_Why_do_{}_while? 1/2
01/02/2018 JTN002 - MinUnit -- a minimal unit testing framework for C

static char * test_foo() {


mu_assert("error, foo != 7", foo == 7);
return 0;
}

static char * test_bar() {


mu_assert("error, bar != 5", bar == 5);
return 0;
}

static char * all_tests() {


mu_run_test(test_foo);
mu_run_test(test_bar);
return 0;
}

int main(int argc, char **argv) {


char *result = all_tests();
if (result != 0) {
printf("%s\n", result);
}
else {
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);

return result != 0;
}

Conclusion
People think that writing a unit testing framework has to be complex. In fact, you can write one in just a
few lines of code, as this tech note shows. Of course, if you have access to a full-featured testing
framework like JUnit, by all means use it. But if you don't, you can still use a simple framework like
MinUnit, or whip up your own in a few hours. There's no excuse for not unit testing.

License
You may use the code in this tech note for any purpose, with the understanding that it comes with NO
WARRANTY.

Appendix: Why do {} while?


I've gotten a number of questions about the use of do {} while in the mu_run_test macro. This is a
standard C idiom for writing a macro that contains multiple statements. For more information, see:
http://www.eskimo.com/~scs/C-faq/q10.4.html

http://www.jera.com/techinfo/jtns/jtn002.html#Appendix:_Why_do_{}_while? 2/2

Potrebbero piacerti anche