Unit tests

Meson verfügt über ein voll funktionsfähiges Unit-Testsystem. Um es zu nutzen, erstellen Sie einfach eine ausführbare Datei und verwenden Sie diese dann in einem Test.

e = executable('prog', 'testprog.c')
test('name of test', e)

Sie können beliebig viele Tests hinzufügen. Sie werden mit dem Befehl meson test ausgeführt.

Meson erfasst die Ausgabe aller Tests und schreibt sie in die Protokolldatei meson-logs/testlog.txt.

Testparameter

Einige Tests erfordern die Verwendung von Kommandozeilenargumenten oder Umgebungsvariablen. Diese sind einfach zu definieren.

test('command line test', exe, args : ['first', 'second'])
test('envvar test', exe2, env : ['key1=value1', 'key2=value2'])

Beachten Sie, dass Sie mehrere Werte als Array angeben müssen.

MALLOC_PERTURB_

Standardmäßig wird die Umgebungsvariable MALLOC_PERTURB_ auf einen zufälligen Wert zwischen 1 und 255 gesetzt. Dies kann helfen, Speicherlecks in Konfigurationen zu finden, die glibc verwenden, einschließlich nicht-GCC-Compilern. Diese Funktion kann deaktiviert werden, wie in test() erläutert.

ASAN_OPTIONS, UBSAN_OPTIONS und MSAN_OPTIONS

Standardmäßig werden die Umgebungsvariablen ASAN_OPTIONS, UBSAN_OPTIONS und MSAN_OPTIONS so gesetzt, dass sie beim Erkennen von Verstößen einen Abbruch auslösen und eine Rückverfolgung (backtrace) liefern. Diese Funktion kann deaktiviert werden, wie in test() erläutert.

Abdeckung (Coverage)

Wenn Sie die Messung der Abdeckung aktivieren, indem Sie Meson das Kommandozeilenargument -Db_coverage=true übergeben, können Sie nach Ausführung der Tests Abdeckungsberichte generieren (die Ausführung der Tests ist erforderlich, um die Liste der aufgerufenen Funktionen zu sammeln). Meson erkennt automatisch, welche Abdeckungswerkzeuge Sie installiert haben, und generiert die entsprechenden Ziele. Diese Ziele sind coverage-xml und coverage-text, die beide von Gcovr (Version 3.3 oder höher) bereitgestellt werden, coverage-sonarqube, das von Gcovr (Version 4.2 oder höher) bereitgestellt wird, und coverage-html, das lcov und GenHTML oder Gcovr benötigt. Als Komfortfunktion wird auch ein übergeordnetes Ziel coverage generiert, das, wenn möglich, alle drei Arten von Abdeckungsberichten erstellt.

Die Ausgabe dieser Befehle wird in das Protokollverzeichnis meson-logs in Ihrem Build-Verzeichnis geschrieben.

Parallelität

Um die Testzeiten zu verkürzen, führt Meson standardmäßig mehrere Unit-Tests parallel aus. Es gibt jedoch Tests, die nicht parallel ausgeführt werden können, da sie exklusiven Zugriff auf eine Ressource wie eine Datei oder einen D-Bus-Namen benötigen. Diese Tests müssen Sie mit einem Schlüsselwortargument angeben.

test('unique test', t, is_parallel : false)

Meson stellt dann sicher, dass keine anderen Unit-Tests gleichzeitig laufen. Nicht-parallele Tests dauern länger, daher wird empfohlen, Ihre Unit-Tests so zu schreiben, dass sie wann immer möglich parallel ausführbar sind.

Standardmäßig verwendet Meson so viele gleichzeitige Prozesse wie Kerne auf dem Testrechner vorhanden sind. Sie können dies mit der Umgebungsvariable MESON_TESTTHREADS überschreiben, wie hier gezeigt.

$ MESON_TESTTHREADS=5 meson test

Wenn MESON_TESTTHREADS auf 0 gesetzt wird, wird das Standardverhalten (Anzahl der Kerne) aktiviert, während ein ungültiger Wert dazu führt, dass die Anzahl der Jobs auf 1 gesetzt wird.

Prioritäten

(hinzugefügt in Version 0.52.0)

Tests können eine Priorität zugewiesen bekommen, die bestimmt, wann ein Test *gestartet* wird. Tests mit höherer Priorität werden zuerst gestartet, Tests mit niedrigerer Priorität später. Die Standardpriorität ist 0. Meson gibt keine Garantie für die Reihenfolge von Tests mit identischer Priorität.

test('started second', t, priority : 0)
test('started third', t, priority : -50)
test('started first', t, priority : 1000)

Beachten Sie, dass die Testpriorität nur die Startreihenfolge der Tests beeinflusst. Nachfolgende Tests werden davon beeinflusst, wie lange vorherige Tests dauern. Es ist daher möglich, dass ein Test mit höherer Priorität noch läuft, während Tests mit niedrigerer Priorität und kürzerer Laufzeit bereits abgeschlossen sind.

Übersprungene Tests und harte Fehler

Manchmal kann ein Test erst zur Laufzeit feststellen, dass er nicht ausgeführt werden kann.

Für das Standardprotokoll für die exitcode-Tests ist der GNU-Standardansatz in diesem Fall, das Programm mit dem Fehlercode 77 zu beenden. Meson erkennt dies und meldet diese Tests als übersprungen statt als fehlgeschlagen. Dieses Verhalten wurde in Version 0.37.0 hinzugefügt.

Für TAP-basierte Tests sollten übersprungene Tests eine einzelne Zeile ausgeben, die mit 1..0 # SKIP beginnt.

Darüber hinaus kann es vorkommen, dass ein Test so fehlerhaft eingerichtet ist, dass er fehlschlägt, auch wenn er als erwartetes Fehlschlagen markiert ist. Der GNU-Standardansatz in diesem Fall ist, das Programm mit dem Fehlercode 99 zu beenden. Wiederum erkennt Meson dies und meldet diese Tests als ERROR, wobei die Einstellung von should_fail ignoriert wird. Dieses Verhalten wurde in Version 0.50.0 hinzugefügt.

Test-Werkzeug

Das Ziel des Meson-Testwerkzeugs ist es, eine einfache Möglichkeit zu bieten, Tests auf verschiedene Weise auszuführen. Das Werkzeug ist dafür ausgelegt, im Build-Verzeichnis ausgeführt zu werden.

Das Einfachste ist, einfach alle Tests auszuführen.

$ meson test

Teilmengen von Tests ausführen

Zur Verdeutlichung betrachten wir die meson.build-Datei mit


test('A', ..., suite: 'foo')
test('B', ..., suite: ['foo', 'bar'])
test('C', ..., suite: 'bar')
test('D', ..., suite: 'baz')

Tests nach Namen angeben wie

$ meson test A D

Sie können Tests aus bestimmten (Unter-)Projekten ausführen

$ meson test (sub)project_name:

oder einen bestimmten Test in einem bestimmten Projekt

$ meson test (sub)project_name:test_name

Seit Version 1.2.0 können Sie Wildcards in Projekt- und Testnamen verwenden. Zum Beispiel, um alle Tests auszuführen, die mit "foo" beginnen, und alle Tests aus Projekten, die mit "bar" beginnen

$ meson test "foo*" "bar*:"

Tests, die zu einer Suite suite gehören, können wie folgt ausgeführt werden

$ meson test --suite (sub)project_name:suite

Seit Version 0.46 kann (sub)project_name weggelassen werden, wenn es sich um das oberste Projekt handelt.

Mehrere Suiten werden wie folgt angegeben

$ meson test --suite foo --suite bar

HINWEIS: Wenn Sie sowohl Suiten als auch spezifische Testnamen angeben, müssen die Testnamen in den Suiten enthalten sein. Dies ist jedoch redundant - es wäre nützlicher, entweder spezifische Testnamen oder Suiten anzugeben.

Andere Testoptionen

Manchmal müssen Sie die Tests mehrmals ausführen, was wie folgt geschieht

$ meson test --repeat=10

Meson setzt die Umgebungsvariable MESON_TEST_ITERATION auf die aktuelle Iteration des Tests (hinzugefügt 1.5.0).

Das Aufrufen von Tests über eine Hilfs-Executable wie Valgrind kann mit dem Argument --wrap erfolgen

$ meson test --wrap=valgrind testname

Argumente für das Wrapper-Binary können wie folgt angegeben werden

$ meson test --wrap='valgrind --tool=helgrind' testname

Meson unterstützt auch das Ausführen von Tests unter GDB. Allein durch die Ausführung

$ meson test --gdb testname

Meson startet gdb, alles ist vorbereitet, um den Test auszuführen. Geben Sie einfach run in der GDB-Befehlszeile ein, um das Programm zu starten.

Der zweite Anwendungsfall ist ein Test, der nur selten abstürzt. In diesem Fall können Sie den folgenden Befehl aufrufen

$ meson test --gdb --repeat=10000 testname

Dies führt den Test bis zu 10.000 Mal automatisch unter GDB aus. Wenn das Programm abstürzt, hält GDB an und der Benutzer kann die Anwendung debuggen. Beachten Sie, dass Test-Timeouts in diesem Fall deaktiviert sind, sodass meson test gdb nicht beendet, während der Entwickler noch debuggt. Der Nachteil ist, dass der Test-Runner ewig wartet, wenn die Test-Binary einfriert.

Manchmal ist das GDB-Binary nicht in der PATH-Variable oder der Benutzer möchte einen GDB-Ersatz verwenden. Daher kann das aufgerufene GDB-Programm angegeben werden (hinzugefügt 0.52.0)

$ meson test --gdb --gdb-path /path/to/gdb testname
$ meson test --print-errorlogs

Tests können interaktiv mit der Option --interactive ausgeführt werden. meson test --interactive ruft Tests auf, bei denen Standardausgabe, Standardeingabe und Standardfehlerausgabe direkt mit dem aufrufenden Terminal verbunden sind. Dies kann nützlich sein, wenn Ihr Test ein Integrationstest ist, der in einem Container oder einer virtuellen Maschine ausgeführt wird, in der eine Debug-Shell gestartet wird, falls er fehlschlägt (hinzugefügt 1.5.0)

$ meson test --interactive testname

Meson meldet die von den fehlgeschlagenen Tests erzeugte Ausgabe zusammen mit anderen nützlichen Informationen wie den Umgebungsvariablen. Dies ist beispielsweise nützlich, wenn Sie die Tests auf Travis-CI, Jenkins und ähnlichen Plattformen ausführen.

Standardmäßig ist die Ausgabe von Tests auf die letzten 100 Zeilen beschränkt. Die maximale Anzahl der anzuzeigenden Zeilen kann mit der Option --max-lines konfiguriert werden (hinzugefügt 1.5.0)

$ meson test --max-lines=1000 testname

Timeout

In den Optionen für Testfälle wird die Option timeout in Sekunden angegeben.

Um den Timeout in Testfällen zu deaktivieren, fügen Sie timeout: 0 oder einen negativen Wert hinzu, um eine unendliche Dauer für die Fertigstellung des Testfalls zu ermöglichen.

Zum Ausführen von Tests können Sie ein Kommandozeilenargument angeben, um den Timeout ebenfalls zu überschreiben

$ meson test --timeout-multiplier 0

Weitere Informationen finden Sie in der Kommandozeilenhilfe von Meson, indem Sie meson test -h ausführen.

Alte Hinweise

Wenn meson test bei Ihnen nicht funktioniert, haben Sie wahrscheinlich eine alte Version von Meson. In diesem Fall sollten Sie stattdessen mesontest aufrufen. Wenn mesontest auch nicht funktioniert, haben Sie eine sehr alte Version vor 0.37.0 und sollten ein Upgrade durchführen.

Testergebnisse

Meson schreibt mehrere verschiedene Dateien mit detaillierten Ergebnissen der ausgeführten Tests. Diese werden in $builddir/meson-logs/ geschrieben.

testlog.json

Dies ist keine ordnungsgemäße JSON-Datei, sondern eine Datei, die ein gültiges JSON-Objekt pro Zeile enthält. Diese Datei ist so konzipiert, dass jede Zeile beim Ausführen jedes Tests gestreamt wird, sodass sie als Stream gelesen werden kann, während die Test-Harness läuft.

testlog.junit.xml

Dies ist eine gültige JUnit-XML-Beschreibung aller ausgeführten Tests. Sie wird nicht gestreamt und nur einmal geschrieben, nachdem alle Tests abgeschlossen sind.

Wenn Tests das tap-Protokoll verwenden, wird jeder Test als Testsuite-Container aufgezeichnet, wobei jeder Fall nach der Nummer des Ergebnisses benannt wird.

Wenn Tests das gtest-Protokoll verwenden, injiziert Meson Argumente in den Test, um seine eigene JUnit-XML zu generieren, die Meson als Teil dieser XML-Datei einschließt.

Neu ab 0.55.0

Die Ergebnisse der Suche sind