Skip to content

Commit

Permalink
Improve the test-templates README and update the templates to current…
Browse files Browse the repository at this point in the history
… practice.
  • Loading branch information
jralls committed Jul 28, 2015
1 parent 124a247 commit 2663dc9
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 45 deletions.
29 changes: 21 additions & 8 deletions test-templates/README
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,35 @@ If there is already a test directory with make check tests in it, copy
the contents of the Makefile.am in this directory to the existing
Makefile.am; otherwise, copy the Makefile.am to your test directory.

Copy test-module.c and test-suite.c to your test directory and rename
them appropriately. You will very likely want several copies of
test-suite.c, one corresponding to each c file in the module directory
that you're testing.
There are two groups of templates here: testmain.c is for a standalone test
program that doesn't group tests into suites. test-module.c and test-suite.c
support collecting a large number of tests separated in suites into a single
test program. In most cases you'll want to use the latter.

For a single file test program, copy testmain.c into your test directory,
renaming it appropriately. Write fixtures and test functions as needed and
register them in main(). Create a target in Makefile.am which has this file as
its source.

To use suites, copy test-module.c and test-suite.c to your test directory and
rename them appropriately. You will very likely want several copies of
test-suite.c, one corresponding to each c file in the module directory that
you're testing.

Edit the test module file to call the (renamed) test_suite_module() in
each test-suite file. Add tests and fixtures as needed to the
test-suite files and add them to the (renamed) test_suite_module()
test-suite files and register them in the (renamed) test_suite_module()
function.

Edit Makefile.am according to the comments in the file.

Run autogen.sh and configure. "make check" will run all tests; "make
test" will run only the GLib unit tests not guarded by conditionals
(see test-suite.c).
Run autogen.sh and configure. "make check" will run all tests; "make test" will
run only the GLib unit tests not guarded by conditionals (see test-suite.c). For
more control, use gtester as documented in the GLib docs.

See http://www.mail-archive.com/[email protected]/msg06994.html
and http://library.gnome.org/devel/glib/stable/glib-Testing.html
for detailed documentation.

There are some helpful macros and message-trapping functions in
src/test-core/unittest-support.h.
5 changes: 1 addition & 4 deletions test-templates/test-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ extern GTestSuite *test_suite_module3();
extern GTestSuite *test_suite_module4();

int
main (int argc,
char *argv[])
main (int argc, char *argv[])
{
qof_init(); /* You may or may not need this, depending on
* whether the module you're testing or any
Expand All @@ -48,5 +47,3 @@ main (int argc,

return g_test_run(); /* Run the result */
}


45 changes: 27 additions & 18 deletions test-templates/test-suite.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,42 @@
* Boston, MA 02110-1301, USA [email protected] *
\********************************************************************/

/* This is a template test suite. Copy it to the test directory and name it for
* the corresponding file you're testing with a "utest-" prefix. Add it to the
* test_program_SOURCES in Makefile.am.
*/
#include <config.h>
#include <glib.h>
/* This is optional; you only need it if you have external fixtures or mocks. */
#include "test_module_support.h"
#include <unittest-support.h>
/* Header for this module and any others that you need */
#include <module_1.h>

/* Declare the test path for the suite. g_test_add_func automatically
* creates a nested set of test suites for us based on this path. */
static const gchar *suitename = "module/module_1";

/* Test fixture: A struct, a setup function, and a teardown function are passed to g_test_add(); add getters, setters, and whatever other functions you need to call from your test functions. */
/* Test fixture: A struct, a setup function, and a teardown function are passed
* to g_test_add(); add getters, setters, and whatever other functions you need
* to call from your test functions.
*/
typedef struct
{
gint foo;
gdouble bar;
} Fixture;

static void
setup_module_test(Fixture *fixture, gconstpointer pData)
setup (Fixture *fixture, gconstpointer pData)
{
/* Do something useful */
/* Whatever is needed to populate the fixture and initialize your module for
* running a single test.
*/
}

static void
teardown_module_test(Fixture *fixture, gconstpointer pData)
teardown (Fixture *fixture, gconstpointer pData)
{
/* Clean up after ourselves */
/* Whatever cleanup is needed at the end of the test. */
}

static void
Expand Down Expand Up @@ -92,22 +100,23 @@ test_performance_function( void )
* You can also emit arbitrary messages into the test report with
* g_test_message( const char* format, ... )
*/
GTestSuite*
test_suite_module1 ( void )
void
test_suite_module1 (void)
{
Datatype data = something();
g_test_add_func( suitename, test_function );
g_test_add_data_func( suitename, (gconstpointer)(&data),
test_function_with_data );
g_test_add( suitename, Fixture,
data,
setup_module_test,
test_function_with_fixture,
teardown_module_test);
GNC_TEST_ADD_FUNC (suitename, "Test Name 1", test_function);
{
gchar *testpath = g_strdup_printf ("%s/Test Name 2", suitename);
g_test_add_data_func( suitename, (gconstpointer)(&data),
test_function_with_data );
g_free (testpath);
}
GNC_TEST_ADD (suitename, "Test Name 3", Fixture, data, setup,
test_function_with_fixture, teardown);
/* Other conditionals are g_test_quick(), g_test_slow(), and
* g_test_thorough() */
if ( g_test_perf() )
{
g_test_add_func( suitename, test_performance_func );
GNC_TEST_ADD_FUNC (suitename, "Test Name 4", test_performance_func);
}
}
82 changes: 67 additions & 15 deletions test-templates/testmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,78 @@
\********************************************************************/


/* This is a template test program. Copy it to the test sudirectory and rename it test_modulename.c. (Use the same modulename that you gave Makefile.am in the same directory.
Write and link other test files */
#include <glib/glib.h>
/**
* This is a template test program. Copy it to the test sudirectory and rename
* it test_modulename.c. (Use the same modulename that you gave Makefile.am in
* the same directory.
*/
#include <config.h>
#include <glib.h>
/* Add any headers you need for the functions you're testing. */

/* Test fixture: A struct, a setup function, and a teardown function are passed
* to g_test_add(); add getters, setters, and whatever other functions you need
* to call from your test functions.
*/
typedef struct
{
int a;
char* b;
} Fixture;

static void
setup (Fixture *fixture, gconstpointer pData)
{
/* Whatever is needed to populate the fixture and initialize your module for
* running a single test.
*/
}

static void
teardown (Fixture *fixture, gconstpointer pData)
{
/* Whatever cleanup is needed at the end of the test. */
}

static void
example_without_fixture (void)
{
/* This test doesn't need the fixture or any preconditions. You might use
* this for a constructor test, for example.
*/
}

static void
example_with_data( gconstpointer data )
{
/* We want to be able to call this function more than once with different
* data.
*/
}

static void
example_with_fixture (Fixture *fixture, gconstpointer pData)
{
/* This one uses the fixture. */
}

int
main (int argc,
char *argv[])
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv); // initialize test program
/* Add test functions and suites. See
qof_init(); /* You may or may not need this, depending on
* whether the module you're testing or any
* dependencies use GObject. */
qof_log_init_filename_special("/dev/null"); /* Initialize the
* gnucash logging system. Your tests will
* crash on the first logging call otherwise */
g_test_init (&argc, &argv, NULL); // initialize test program
/* Add test functions. See
* http://library.gnome.org/devel/glib/stable/glib-Testing.html for
* details. Unfortunately, GLib-Testing doesn't provide the automatic
* registration features of more sophisitcated frameworks. */
g_test_add_func ("/TESTPROG/Test Case Name", test_case_test_func);
ScannerFixture, // fixture structure type
NULL, // unused data argument
scanner_fixture_setup, // fixture setup
test_scanner_symbols, // test function
scanner_fixture_teardown); // fixture teardown
g_test_add_func ("/TESTPROG/Test Case Name 1", example_without_fixture);
g_test_add_data_func ("/TESTPROG/Test Case Name 2", NULL);
g_test_add ("/TESTPROG/Test Case Name", Fixture, NULL, setup,
example_with_fixture, teardown);
return g_test_run();
}


0 comments on commit 2663dc9

Please sign in to comment.