v2.0.0
Loading...
Searching...
No Matches
python_test_helper.h File Reference

QtTest convenience layer on top of UTILSLIB::PythonRunner for cross-validating MNE-CPP results against MNE-Python. More...

#include "utils_global.h"
#include "python_runner.h"
#include <Eigen/Core>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QVariantMap>
Include dependency graph for python_test_helper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  UTILSLIB::PythonTestHelper

Namespaces

namespace  UTILSLIB
 Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).

Macros

#define GUARD_PYTHON(available, reason)
 Test helper for MNE-Python cross-validation.
#define GUARD_PYTHON_PACKAGE(helper, packageName)
 Skip (or fail) the current test if a Python package is missing.

Detailed Description

QtTest convenience layer on top of UTILSLIB::PythonRunner for cross-validating MNE-CPP results against MNE-Python.

SPDX-License-Identifier: BSD-3-Clause Copyright (c) 2026 MNE-CPP Authors

Author
Christoph Dinh chris.nosp@m.toph.nosp@m..dinh.nosp@m.@mne.nosp@m.-cpp..nosp@m.org
Since
2.2.0
Date
April 2026

Built on UTILSLIB::PythonRunner, this helper adds the thin layer test code needs: a one-shot isAvailable() probe (which caches the result), hasPackage() lookups so a test can announce that it needs e.g. sklearn, and the eval / evalDouble shorthands for running a snippet and parsing its stdout into a number.

The companion GUARD_PYTHON / GUARD_PYTHON_PACKAGE macros QSKIP a test cleanly when Python is missing on developer machines but escalate to QFAIL when MNE_REQUIRE_PYTHON=true so CI runs can never silently skip cross-language regression coverage.

Definition in file python_test_helper.h.

Macro Definition Documentation

◆ GUARD_PYTHON

#define GUARD_PYTHON ( available,
reason )
Value:
do { \
if (!(available)) { \
QFAIL(qPrintable(QString("HARD FAIL (MNE_REQUIRE_PYTHON=true): %1").arg(reason))); \
QSKIP(qPrintable(QString("SKIP: %1").arg(reason))); \
} \
} while (0)

Test helper for MNE-Python cross-validation.

Test-frame convenience class for cross-validating MNE-CPP outputs against MNE-Python reference implementations.

Usage inside a QTest test:

PythonTestHelper py;
if (!py.isAvailable()) {
QSKIP("Python/MNE-Python not available");
}
// Run a Python snippet that computes a reference value
auto result = py.eval("import mne; print(mne.io.read_info('test.fif')['nchan'])");
QVERIFY(result.success);
QCOMPARE(result.stdOut.trimmed().toInt(), expectedNchan);
// Or run a script and parse a numeric output
double pyValue = py.evalDouble("import numpy as np; print(np.linalg.norm(np.ones(10)))");
QVERIFY(qAbs(cppValue - pyValue) < 1e-6);

When MNE-Python is not installed, tests should QSKIP gracefully — but never silently. Use the GUARD_PYTHON / GUARD_PYTHON_PACKAGE macros to ensure skips are intentional and visible. When the environment variable MNE_REQUIRE_PYTHON=true is set (e.g. in CI), those macros QFAIL instead of QSKIP, so a missing Python installation is treated as a hard error.

Skip (or fail) the current test if Python is not available.

Use this macro at the top of any test slot that requires Python.

  • If MNE_REQUIRE_PYTHON is not set: QSKIP with a clear message.
  • If MNE_REQUIRE_PYTHON=true: QFAIL so the skip is never silent in CI.
Parameters
helperA PythonTestHelper (or bool) — must support operator bool / isAvailable().
reasonHuman-readable reason string.

Definition at line 100 of file python_test_helper.h.

◆ GUARD_PYTHON_PACKAGE

#define GUARD_PYTHON_PACKAGE ( helper,
packageName )
Value:
GUARD_PYTHON((helper).hasPackage(packageName), \
QString("Python package '%1' not available").arg(packageName))
#define GUARD_PYTHON(available, reason)
Test helper for MNE-Python cross-validation.

Skip (or fail) the current test if a Python package is missing.

Parameters
helperA PythonTestHelper instance.
packageNamePackage name string (e.g. "sklearn").

Definition at line 115 of file python_test_helper.h.