On Fri, 16 Oct 2020 at 08:29:48 +0200, Kai Pastor, DG0YT wrote:
> So far, all cases in openorienteering-mapper were tests which were expected
> to be run in the build environment and indeed access the pristine test data
> in the source directory.
> 
> The current issue comes from using Qt's QFINDTESTDATA(), which relies on a
> cpp macro (QT_TESTCASE_BUILDDIR) pointing "to the working directory from
> which the compiler is invoked" in order to "the absolute path of the source
> directory" [!], https://doc.qt.io/qt-5/qtest.html#QFINDTESTDATA .
> QT_TESTCASE_BUILDDIR is defined by Qt's cmake file.

One way this is often done, particularly in the GNOME ecosystem, is to
check for an environment variable that is set by the build system while
running tests. There are often two environment variables - one for the
source directory and one for the build directory - so that tests can
either ask for data files that are distributed with the source code, or
data files that were compiled along with the test itself and placed in
the build directory, if those directories are different.

If the environment variable is not set, there's a fallback that would
be reasonable to use if the test has been installed system-wide,
typically into /usr/libexec/installed-tests (which is something
that various GNOME and GNOME-adjacent packages support doing, for
"as-installed" testing like Debian's autopkgtest: see
<https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests>).
In GLib the fallback is to use dirname(argv[0]), but hard-coding an
installation path would also be reasonable here.

This avoids having to hard-code the path to either the source or build
directory into any binaries, even if test executables and data are going
to be installed into /usr/libexec/installed-tests for "as-installed"
testing.

Some packages need to set environment variables for build-time testing
*anyway*, so that third-party components will find their required data
in the source or build tree: for example, you might need to set PATH,
LD_LIBRARY_PATH, XDG_DATA_DIRS and similar variables. The variables used
by this particular package's tests can be set in the same way.

The implementation that is normally used in GNOME is GLib's
g_test_build_filename(), which works something like this pseudocode:

    if file_type == G_TEST_DIST:
        dir = getenv("G_TEST_SRCDIR")
    elif file_type == G_TEST_BUILT:
        # this branch is the closest equivalent of QFINDTESTDATA
        dir = getenv("G_TEST_BUILDDIR")
    else:
        fatal error

    if dir is null:
        dir = directory containing the running executable

    return join_paths(dir, first_path, ...)

An implementation of the build-system side of this in a simple
Makefile-based build system would look something like:

    export G_TEST_BUILDDIR = $(CURDIR)
    export G_TEST_SRCDIR = $(srcdir)

    check:
            ./test-foo
            ./test-bar

Obviously the code would look a bit different for Autotools, CMake or
Meson, but all are capable of doing this (Autotools uses
AM_TESTS_ENVIRONMENT, CMake uses
set_tests_properties(... PROPERTIES ENVIRONMENT ...), Meson uses
test(..., env : ...)).

I assume qmake would also be able to do this, but I don't know how.

    smcv

Reply via email to