1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<title>Writing Tests | lily-test</title>
</head>
<body>
<div id="flex-root">
<iframe id="toc" src="table-of-contents.html"></iframe>
<div id="content">
<h1>Writing Tests</h1>
<p>A basic unit test file looks like this:</p>
<pre><code>
#include "lily-test.h"
LILY_FILE_BEGIN(example_file)
LILY_TEST("example test 1")
{
CHECK_EQ(1+1, 2, "%d");
}
#include LILY_PUSH_TEST()
LILY_TEST("example test 2")
{
CHECK_LT(3.0, 4.0, "%0.2f");
}
#include LILY_PUSH_TEST()
#define LILY_FILE_END
#include LILY_REGISTER_TESTS()
</code></pre>
<p>This will define a function pointer <code>example_file</code> with signature <code>void ()</code> that, when called, will execute the two tests and display to stderr any errors that they generate. While there is more boilerplate than in comparable C++ libraries, this means that lily-test supports test auto-registration. To add a new test, just use the <code>LILY_TEST</code> macro as shown, and then follow the function body with <code>#include LILY_PUSH_TEST()</code> to register it. These macros will only work correctly when used between a <code>LILY_FILE_BEGIN</code> and <code>LILY_FILE_END</code> block, and only when used <em>together</em>; using <code>LILY_TEST</code> without a <code>LILY_PUSH_TEST</code> is probably going to throw up a ton of compile errors.</p>
<h2>Using a single file</h2>
<p>For very small projects, you may be able to get away with using only a single unit test file. In this case, you should set it up along the following lines:</p>
<pre><code>
#define LILY_IMPLEMENTATION
#include "lily-test.h"
/* any includes or code to get your tests working */
LILY_FILE_BEGIN(tests)
/* test definitions... */
#define LILY_FILE_END
#include LILY_REGISTER_TESTS()
int main()
{
lily_begin();
tests();
lily_finish();
return 0;
}
</code></pre>
However, in most cases you will want to have multiple test files.
<h2>Multiple test files</h2>
<p>You will need, in addition to your unit test files, a header file that contains extern declarations of the function pointers defined by your files and a main C source file that contains a <code>main</code> function to run all of the function pointers. A nice way to set this up is to use X-macros, like this:</p>
<pre><code>
/* tests.h */
#define TESTS \
X(suite_1) \
X(suite_2) \
X(suite_3) \
#define X(suite) extern void (*suite)();
TESTS
#undef X
</code></pre>
<pre><code>
/* tests_main.c */
#define LILY_IMPLEMENTATION
#include "lily-test.h"
int main()
{
lily_begin();
#define X(suite) suite();
TESTS
#undef X
lily_finish();
return 0;
}
</code></pre>
<p>This is convenient, because it means that when you add a new test file you need only add a single line to the definition of the <code>TESTS</code> macro in <code>tests.h</code> and all of the other relevant code is added for you automatically.<p>
<p>Note that exactly ONE file should define <code>LILY_IMPLEMENTATION</code>. I find it reasonable to make this the same file with the implementation of <code>main</code> but YMMV.</p>
</div>
</div>
<div id="footer">
<a id="prev" href="01-introduction.html">⇐ Previous</a>
<a id="next" href="03-assertions.html">Next ⇒</a>
</div>
</body>
</html>
|