1 /* tinytest_demo.c -- Copyright 2009-2012 Nick Mathewson
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
6 * 1. Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * 2. Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * 3. The name of the author may not be used to endorse or promote products
12 * derived from this software without specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /* Welcome to the example file for tinytest! I'll show you how to set up
28 * some simple and not-so-simple testcases. */
30 /* Make sure you include these headers. */
32 #include "tinytest_macros.h"
39 /* ============================================================ */
41 /* First, let's see if strcmp is working. (All your test cases should be
42 * functions declared to take a single void * as an argument.) */
44 test_strcmp(void *data
)
46 (void)data
; /* This testcase takes no data. */
48 /* Let's make sure the empty string is equal to itself */
50 /* This macro tells tinytest to stop the current test
51 * and go straight to the "end" label. */
52 tt_abort_msg("The empty string was not equal to itself");
55 /* Pretty often, calling tt_abort_msg to indicate failure is more
56 heavy-weight than you want. Instead, just say: */
57 tt_assert(strcmp("testcase", "testcase") == 0);
59 /* Occasionally, you don't want to stop the current testcase just
60 because a single assertion has failed. In that case, use
62 tt_want(strcmp("tinytest", "testcase") > 0);
64 /* You can use the tt_*_op family of macros to compare values and to
65 fail unless they have the relationship you want. They produce
66 more useful output than tt_assert, since they display the actual
67 values of the failing things.
69 Fail unless strcmp("abc, "abc") == 0 */
70 tt_int_op(strcmp("abc", "abc"), ==, 0);
72 /* Fail unless strcmp("abc, "abcd") is less than 0 */
73 tt_int_op(strcmp("abc", "abcd"), < , 0);
75 /* Incidentally, there's a test_str_op that uses strcmp internally. */
76 tt_str_op("abc", <, "abcd");
79 /* Every test-case function needs to finish with an "end:"
80 label and (optionally) code to clean up local variables. */
85 /* ============================================================ */
87 /* Now let's mess with setup and teardown functions! These are handy if
88 you have a bunch of tests that all need a similar environment, and you
89 want to reconstruct that environment freshly for each one. */
91 /* First you declare a type to hold the environment info, and functions to
92 set it up and tear it down. */
94 /* We're just going to have couple of character buffer. Using
95 setup/teardown functions is probably overkill for this case.
97 You could also do file descriptors, complicated handles, temporary
102 /* The setup function needs to take a const struct testcase_t and return
105 setup_data_buffer(const struct testcase_t
*testcase
)
107 struct data_buffer
*db
= malloc(sizeof(struct data_buffer
));
109 /* If you had a complicated set of setup rules, you might behave
110 differently here depending on testcase->flags or
111 testcase->setup_data or even or testcase->name. */
113 /* Returning a NULL here would mean that we couldn't set up for this
114 test, so we don't need to test db for null. */
117 /* The clean function deallocates storage carefully and returns true on
120 clean_data_buffer(const struct testcase_t
*testcase
, void *ptr
)
122 struct data_buffer
*db
= ptr
;
130 /* Finally, declare a testcase_setup_t with these functions. */
131 struct testcase_setup_t data_buffer_setup
= {
132 setup_data_buffer
, clean_data_buffer
136 /* Now let's write our test. */
138 test_memcpy(void *ptr
)
140 /* This time, we use the argument. */
141 struct data_buffer
*db
= ptr
;
143 /* We'll also introduce a local variable that might need cleaning up. */
146 /* Let's make sure that memcpy does what we'd like. */
147 strcpy(db
->buffer1
, "String 0");
148 memcpy(db
->buffer2
, db
->buffer1
, sizeof(db
->buffer1
));
149 tt_str_op(db
->buffer1
, ==, db
->buffer2
);
151 /* Now we've allocated memory that's referenced by a local variable.
152 The end block of the function will clean it up. */
153 mem
= strdup("Hello world.");
156 /* Another rather trivial test. */
157 tt_str_op(db
->buffer1
, !=, mem
);
160 /* This time our end block has something to do. */
165 /* ============================================================ */
167 /* Now we need to make sure that our tests get invoked. First, you take
168 a bunch of related tests and put them into an array of struct testcase_t.
171 struct testcase_t demo_tests
[] = {
172 /* Here's a really simple test: it has a name you can refer to it
173 with, and a function to invoke it. */
174 { "strcmp", test_strcmp
, },
176 /* The second test has a flag, "TT_FORK", to make it run in a
177 subprocess, and a pointer to the testcase_setup_t that configures
179 { "memcpy", test_memcpy
, TT_FORK
, &data_buffer_setup
},
181 /* The array has to end with END_OF_TESTCASES. */
185 /* Next, we make an array of testgroups. This is mandatory. Unlike more
186 heavy-duty testing frameworks, groups can't nest. */
187 struct testgroup_t groups
[] = {
189 /* Every group has a 'prefix', and an array of tests. That's it. */
190 { "demo/", demo_tests
},
197 main(int c
, const char **v
)
199 /* Finally, just call tinytest_main(). It lets you specify verbose
200 or quiet output with --verbose and --quiet. You can list
203 tinytest-demo demo/memcpy
205 or use a ..-wildcard to select multiple tests with a common
208 tinytest-demo demo/..
210 If you list no tests, you get them all by default, so that
211 "tinytest-demo" and "tinytest-demo .." mean the same thing.
214 return tinytest_main(c
, v
, groups
);