The function to run tests in an SRunner is defined as follows:
void srunner_run_all (SRunner * sr, enum print_output print_mode);
This function does two things:
print_mode specified.
For SRunners that have already been run, there is also a separate printing function defined as follows:
void srunner_print (SRunner *sr, enum print_output print_mode);
The enumeration values of print_output defined in Check that
parameter print_mode can assume are as follows:
CK_SILENTCK_MINIMALCK_NORMALCK_VERBOSECK_ENVCK_VERBOSITY,
which can have the values "silent", "minimal", "normal", "verbose". If
the variable is not found or the value is not recognized, the print
mode is set to CK_NORMAL.
With the CK_NORMAL flag specified in our main(), let's
rerun make check now. As before, we get the following satisfying
output:
Running suite(s): Money
0%: Checks: 1, Failures: 1, Errors: 0
check_money.c:10:F:Core:test_money_create: Amount not set correctly on
creation
FAIL: check_money
==================================================
1 of 1 tests failed
Please report to check-devel@lists.sourceforge.net
==================================================
The first number in the summary line tells us that 0% of our tests passed, and the rest of the line tells us that there was one check in total, and of those checks, one failure and zero errors. The next line tells us exactly where that failure occurred, and what kind of failure it was (P for pass, F for failure, E for error).
After that we have some higher level output generated by Automake: the
check_money program failed, and the bug-report address given in
configure.ac is printed.
Let's implement the money_amount function, so that it will pass
its tests. We first have to create a Money structure to hold the
amount, and then implement the function to return the correct amount:
--- src/money.3.c 2006-11-21 18:06:37.457159768 -0500
+++ src/money.4.c 2006-11-21 18:06:37.490154752 -0500
@@ -1,6 +1,11 @@
#include <stdlib.h>
#include "money.h"
+struct Money
+{
+ int amount;
+};
+
Money *
money_create (int amount, char *currency)
{
@@ -10,7 +15,7 @@
int
money_amount (Money * m)
{
- return 0;
+ return m->amount;
}
char *
We will now rerun make check and... what's this? The output is now as follows:
Running suite(s): Money
0%: Checks: 1, Failures: 0, Errors: 1
check_money.c:5:E:Core:test_money_create: (after this point) Received
signal 11 (Segmentation fault)
What does this mean? Note that we now have an error, rather than a
failure. This means that our unit test either exited early, or was
signaled. Next note that the failure message says “after this
point”; This means that somewhere after the point noted
(check_money.c, line 5) there was a problem: signal 11 (a.k.a.
segmentation fault). The last point reached is set on entry to the
unit test, and after every call to fail_unless(),
fail(), or the special function mark_point(). For
example, if we wrote some test code as follows:
stuff_that_works ();
mark_point ();
stuff_that_dies ();
then the point returned will be that marked by mark_point().
The reason our test failed so horribly is that we haven't implemented
money_create() to create any Money. We'll go ahead and
implement that, the symmetric money_free(), and
money_currency() too, in order to make our unit test pass again:
--- src/money.4.c 2006-11-21 18:06:37.490154752 -0500
+++ src/money.5.c 2006-11-21 18:06:37.522149888 -0500
@@ -4,12 +4,21 @@
struct Money
{
int amount;
+ char *currency;
};
Money *
money_create (int amount, char *currency)
{
- return NULL;
+ Money *m = malloc (sizeof (Money));
+ if (m == NULL)
+ {
+ return NULL;
+ }
+
+ m->amount = amount;
+ m->currency = currency;
+ return m;
}
int
@@ -21,11 +30,12 @@
char *
money_currency (Money * m)
{
- return NULL;
+ return m->currency;
}
void
money_free (Money * m)
{
+ free (m);
return;
}