[gtk/docs-gtk-org] glib: Add GTest API overview
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/docs-gtk-org] glib: Add GTest API overview
- Date: Tue, 10 Aug 2021 23:23:19 +0000 (UTC)
commit 45a5d6c2da4df41fe0d5fdcf47d0f08c6b5a8ea9
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue Aug 10 22:49:32 2021 +0100
glib: Add GTest API overview
glib/glib/glib.toml.in | 1 +
glib/glib/meson.build | 1 +
glib/glib/testing.md | 176 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 178 insertions(+)
---
diff --git a/glib/glib/glib.toml.in b/glib/glib/glib.toml.in
index b44e0a05a9..c4946257db 100644
--- a/glib/glib/glib.toml.in
+++ b/glib/glib/glib.toml.in
@@ -36,6 +36,7 @@ content_files = [
"error-reporting.md",
"main-loop.md",
"reference-counting.md",
+ "testing.md",
]
content_images = [
"mainloop-states.gif",
diff --git a/glib/glib/meson.build b/glib/glib/meson.build
index 493937b685..b2cd21e1e6 100644
--- a/glib/glib/meson.build
+++ b/glib/glib/meson.build
@@ -2,6 +2,7 @@ expand_content_files = [
'error-reporting.md',
'main-loop.md',
'reference-counting.md',
+ 'testing.md',
]
glib_gir = meson.current_source_dir() / 'GLib-2.0.gir'
diff --git a/glib/glib/testing.md b/glib/glib/testing.md
new file mode 100644
index 0000000000..b93f8187f0
--- /dev/null
+++ b/glib/glib/testing.md
@@ -0,0 +1,176 @@
+Title: Testing Framework
+
+# Testing Framework
+
+GLib provides a framework for writing and maintaining unit tests in parallel
+to the code they are testing. The API is designed according to established
+concepts found in the other test frameworks (JUnit, NUnit, RUnit), which in
+turn is based on smalltalk unit testing concepts.
+
+- Test case: Tests (test methods) are grouped together with their fixture
+ into test cases.
+- Fixture: A test fixture consists of fixture data and setup and teardown
+ methods to establish the environment for the test functions. We use fresh
+ fixtures, i.e. fixtures are newly set up and torn down around each test
+ invocation to avoid dependencies between tests.
+- Test suite: Test cases can be grouped into test suites, to allow subsets
+ of the available tests to be run. Test suites can be grouped into other
+ test suites as well.
+
+The API is designed to handle creation and registration of test suites and
+test cases implicitly. A simple call like:
+
+```c
+g_test_add_func ("/misc/assertions", test_assertions);
+```
+
+creates a test suite called "misc" with a single test case named
+"assertions", which consists of running the `test_assertions` function.
+
+In addition to the traditional `g_assert_true()`, the test framework
+provides an extended set of assertions for comparisons:
+`g_assert_cmpfloat()`, `g_assert_cmpfloat_with_epsilon()`,
+`g_assert_cmpint()`, `g_assert_cmpuint()`, `g_assert_cmphex()`,
+`g_assert_cmpstr()`, `g_assert_cmpmem()` and `g_assert_cmpvariant()`. The
+advantage of these variants over plain `g_assert_true()` is that the
+assertion messages can be more elaborate, and include the values of the
+compared entities.
+
+Note that `g_assert()` should **not** be used in unit tests, since it is a
+no-op when compiling with `G_DISABLE_ASSERT`. Use `g_assert()` in production
+code, and `g_assert_true()` in unit tests.
+
+A full example of creating a test suite with two tests using fixtures:
+
+```c
+#include <glib.h>
+#include <locale.h>
+
+typedef struct {
+ MyObject *obj;
+ OtherObject *helper;
+} MyObjectFixture;
+
+static void
+my_object_fixture_set_up (MyObjectFixture *fixture,
+ gconstpointer user_data)
+{
+ fixture->obj = my_object_new ();
+ my_object_set_prop1 (fixture->obj, "some-value");
+ my_object_do_some_complex_setup (fixture->obj, user_data);
+
+ fixture->helper = other_object_new ();
+}
+
+static void
+my_object_fixture_tear_down (MyObjectFixture *fixture,
+ gconstpointer user_data)
+{
+ g_clear_object (&fixture->helper);
+ g_clear_object (&fixture->obj);
+}
+
+static void
+test_my_object_test1 (MyObjectFixture *fixture,
+ gconstpointer user_data)
+{
+ g_assert_cmpstr (my_object_get_property (fixture->obj), ==, "initial-value");
+}
+
+static void
+test_my_object_test2 (MyObjectFixture *fixture,
+ gconstpointer user_data)
+{
+ my_object_do_some_work_using_helper (fixture->obj, fixture->helper);
+ g_assert_cmpstr (my_object_get_property (fixture->obj), ==, "updated-value");
+}
+
+int
+main (int argc, char *argv[])
+{
+ setlocale (LC_ALL, "");
+
+ g_test_init (&argc, &argv, NULL);
+
+ // Define the tests.
+ g_test_add ("/my-object/test1", MyObjectFixture, "some-user-data",
+ my_object_fixture_set_up, test_my_object_test1,
+ my_object_fixture_tear_down);
+ g_test_add ("/my-object/test2", MyObjectFixture, "some-user-data",
+ my_object_fixture_set_up, test_my_object_test2,
+ my_object_fixture_tear_down);
+
+ return g_test_run ();
+}
+```
+
+### Integrating GTest in your project
+
+If you are using the Meson build system, you will typically use the provided
+`test()` primitive to call the test binaries, e.g.:
+
+```
+test(
+ 'foo',
+ executable('foo', 'foo.c', dependencies: deps),
+ env: [
+ 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
+ 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
+ ],
+)
+
+test(
+ 'bar',
+ executable('bar', 'bar.c', dependencies: deps),
+ env: [
+ 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
+ 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
+ ],
+)
+```
+
+If you are using Autotools, you're strongly encouraged to use the Automake
+TAP harness; GLib provides template files for easily integrating with it:
+
+- `glib-tap.mk`
+- `tap-test`
+- `tap-driver.sh`
+
+You can copy these files in your own project's root directory, and then set
+up your `Makefile.am` file to reference them, for instance:
+
+```
+include $(top_srcdir)/glib-tap.mk
+
+# test binaries
+test_programs = \
+ foo \
+ bar
+
+# data distributed in the tarball
+dist_test_data = \
+ foo.data.txt \
+ bar.data.txt
+
+# data not distributed in the tarball
+test_data = \
+ blah.data.txt
+```
+
+Make sure to distribute the TAP files, using something like the following in
+your top-level `Makefile.am`:
+
+```
+EXTRA_DIST += \
+ tap-driver.sh \
+ tap-test
+```
+
+`glib-tap.mk` will be distributed implicitly due to being included in a
+`Makefile.am`. All three files should be added to version control.
+
+If you don't have access to the Autotools TAP harness, you can use the
+gtester and gtester-report tools, and use the `glib.mk` Automake template
+provided by GLib. Note, however, that since GLib 2.62, gtester and
+gtester-report have been deprecated in favour of using TAP. The `--tap`
+argument to tests is enabled by default as of GLib 2.62.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]