pytest-Plugin

ecu.test code enthält ein pytest-Plugin, das ein komfortables Reporting der Testergebnisse von ecu.test code nach test.guide ermöglicht. Es wandelt automatisch jede Assertion in einen Testschritt um, sammelt Parameter und benutzerdefinierte Eigenschaften und zeichnet Logs, stdout oder stderr auf.

Voraussetzungen

Einrichtung

  1. Setzen Sie die erforderlichen Umgebungsvariablen:

    • TESTGUIDE_URL: Basis-URL Ihrer test.guide-Instanz (ohne abschließenden Schrägstrich).

    • TESTGUIDE_PROJECT_ID: Numerische Projekt-ID (Tooltip beim Überfahren des Projektnamens).

    • TESTGUIDE_AUTH_KEY: Ihr persönlicher Authentifizierungsschlüssel (in test.guide unter „Authentication keys“ erstellen).

    Die Startkonfiguration des mitgelieferten Demo-Workspace erlaubt es Ihnen, diese Werte in einem Visual-Studio-Code-Dialog einzugeben. Sie können sie aber auch manuell setzen:

    Linux Bash

    export TESTGUIDE_URL="https://ihre.test-guide.instanz"
    export TESTGUIDE_PROJECT_ID=42
    export TESTGUIDE_AUTH_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    

    Windows CMD

    set TESTGUIDE_URL=https://ihre.test-guide.instanz
    set TESTGUIDE_PROJECT_ID=42
    set TESTGUIDE_AUTH_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    
  2. Erstellen oder erweitern Sie tests/pytest.ini, um das Reporting bestandener Assertions zu aktivieren:

    [pytest]
    enable_assertion_pass_hook = True
    enable_verdict_none = true
    

    Löschen Sie nach einer Änderung dieser Datei den Python-Bytecode (__pycache__-Ordner).

  3. Fügen Sie einen Minimaltest hinzu (tests/test_quickstart.py):

    def test_add():
          assert 1 + 1 == 2
    
  4. Führen Sie pytest mit der Upload-Funktion aus:

    pytest tests/test_quickstart.py --upload-to-testguide
    
  5. Ein test.guide-Link mit dem entsprechenden Filter sollte im Pytest-Bericht in der Konsole sichtbar sein. Überprüfen Sie den Testlauf in Ihrem test.guide-Projekt. Wenn Sie enable_assertion_pass_hook aktiviert haben, erscheint die bestandene Assertion als Testschritt mit dem Verdict PASSED.

Fehlerbehebung

  • SSL-Probleme: Wenn Sie manuell konfigurierte SSL-Zertifikate für Ihre test.guide-Instanz verwenden und beim Hochladen von Ergebnissen auf test.guide Probleme auftreten, können Sie pip_system_certs installieren, um die auf Betriebssystemebene konfigurierten Zertifikate zu nutzen. Alternativ können Sie pytest so konfigurieren, dass die Zertifikatsüberprüfung übersprungen wird (nicht empfohlen). Weitere Details finden Sie in der pytest-Dokumentation.

  • Test-Verdict ist nicht PASSED: Stellen Sie sicher, dass enable_assertion_pass_hook = True gesetzt ist, und entfernen Sie veraltete .pyc-Dateien.

Konfiguration

Kommandozeile

pytest-Kommandozeilenoptionen werden beim Aufruf von pytest übergeben und gelten nur für diesen einen Testlauf, z. B.:

pytest test_example.py --upload-to-testguide

Die folgende Tabelle listet alle Kommandozeilenoptionen auf, die von diesem pytest-Plugin bereitgestellt werden. „Standard“ beschreibt, ob die Funktion aktiv ist, wenn die Option nicht verwendet wird.

Option

Default

Description

--upload-to-testguide

False

Upload the result of this test run to test.guide

--export-testguide-report

False

Creates a .report directory in the directory where pytest was invoked. In this directory, you will find all JSON reports and artifacts used for the test.guide upload.

--skip-testguide-ssl

False

Skips the SSL verification for test.guide during the report upload.

pytest.ini

Einträge in pytest.ini definieren persistente Standardwerte für Plugin-Optionen (z. B. enable_assertion_pass_hook = true).

Die folgende Tabelle listet alle .ini-Optionen auf, die von diesem pytest-Plugin bereitgestellt werden:

Name

Type

Default

Description

skip_testguide_ssl

bool

False

Skips the SSL verification for test.guide during the report upload.

testguide_request_timeout

string

20.0

Timeout in seconds for HTTP requests to test.guide. (Applies only when using the report upload.)

enable_verdict_none

bool

False

Test cases (test functions) that do not contain any assertions are reported with verdict NONE in the test.guide report. (This config does not alter the outcome of a test case in the native pytest report.)

Testergebnisse und Verdicts

Das pytest-Plugin stellt jede Assertion als Testschritt dar. Damit auch bestandene Assertions angezeigt werden, muss die pytest-Option enable_assertion_pass_hook aktiviert sein. Diese ist bereits in der mitgelieferten pytest.ini vorkonfiguriert. Achten Sie darauf, Ihre .pyc-Dateien zu löschen, nachdem Sie die enable_assertion_pass_hook-Konfiguration geändert haben. Sie können auch enable_verdict_none setzen, um Testfällen ohne Assertions das Verdict „NONE“ zuzuweisen. Beachten Sie, dass jede Exception, die kein AssertionError ist, dazu führt, dass der Testfall im test.guide-Bericht mit dem Verdict ERROR gemeldet wird. Übersprungene Tests werden mit dem Verdict INCONCLUSIVE gemeldet. Unten finden Sie eine detaillierte Übersicht der Verdicts und ihrer Auslöser.

Warnung

Abweichende Testergebnisse zwischen pytest und test.guide Fehlinterpretationen der Testergebnisse können zu falschen Rückschlüssen über die Qualität eines Testfalls oder Testschritts führen.

  • Das native pytest-Ergebnis (passed, failed, skipped) ist nicht immer identisch mit dem test.guide-Verdict für einen Testfall oder Testschritt.

  • Plugin-Konfigurationsoptionen beeinflussen die Zuordnung von Testergebnissen zu Verdicts.

  1. Überprüfen Sie immer die aktuell aktiven Plugin-Optionen!

  2. Interpretieren Sie Verdicts ausschließlich im Kontext der aktivierten Plugin-Optionen!

Info

Die folgende Tabelle geht davon aus, dass enable_assertion_pass_hook = True in pytest.ini gesetzt ist.

test.guide-Verdict

Auslöser

Konfiguration

PASSED

Es wurde keine Exception ausgelöst, weder während des Setups noch im Testfall selbst.

Standardverhalten

FAILED

Es wurde keine Exception während des Setups ausgelöst, aber im Testfall ein AssertionError.

Standardverhalten

ERROR

Während des Setups oder im Testfall wurde eine andere Exception als AssertionError ausgelöst.

Standardverhalten

INCONCLUSIVE

Der Testfall wurde mittels pytest.mark.skip übersprungen.

Standardverhalten

NONE

Es wurde keine Exception ausgelöst, weder während des Setups noch im Testfall selbst, und der Testfall enthält keine assert-Anweisung.

enable_verdict_none=true

Ausgabeaufzeichnung

Dieses pytest-Plugin kann von pytest erfasste Ausgaben (stdout, stderr oder Logging) als Artefakte im test.guide-Bericht einfügen. Außerdem wird immer dann, wenn ein Testfall das Verdict FAILED oder ERROR erhält, der pytest-Bericht als Artefakt zum Testfall hinzugefügt.

stdout und stderr

Diese Funktion ist standardmäßig aktiviert. Sobald innerhalb eines Testfalls Inhalte auf stdout oder stderr ausgegeben werden, wird ein Artefakt (stdout.log / stderr.log) mit den erfassten Inhalten zum Testfall hinzugefügt. Wenn keine Inhalte erfasst werden, wird auch kein Artefakt erstellt. Diese Funktion kann deaktiviert werden, indem das pytest-Capturing abgeschaltet wird, z. B. mit der CLI-Option -s.

pytest test_example.py -s --upload-to-testguide

Weitere Informationen finden Sie unter Disabling Capturing in der pytest-Dokumentation.

Logging

Ähnlich wie stdout und stderr kann dieses Plugin auch von pytest erfasste Logs (aus der logging-Bibliothek) als Artefakt zum Testfall hinzufügen. Wenn Logs innerhalb eines Testfalls erfasst werden, wird das Artefakt logs.log hinzugefügt. Weitere Informationen zur Aktivierung und Konfiguration von Logging in pytest finden Sie unter How to manage logging in der pytest-Dokumentation.

pytest-Bericht

Sobald ein Testfall das Verdict FAILED oder ERROR erhält, wird der pytest-Bericht als Artefakt (<test_case_name>.log) zum Testfall hinzugefügt. Der pytest-Bericht enthält in der Regel hilfreiche Informationen wie den Traceback, die bei der Analyse von Fehlern in Testfällen unterstützen.

Property-Aufzeichnung

Mit pytest können Sie beliebige Schlüssel/Wert-Metadaten mit Hilfe des Fixtures record_property an einen einzelnen Testfall anhängen (siehe pytest docs). Dieses Plugin überträgt diese Properties als Attribute des entsprechenden Testfalls an test.guide. Diese Funktion ist immer aktiv.

Info

Werte, die nicht vom Typ str sind, werden in ihre repr()-Darstellung konvertiert, sodass komplexe Objekte lesbar werden.

Beispiel

def test_properties(record_property):
   record_property("ecu_sw_version", "v1.2.3")   # str-Wert
   record_property("retries", 2)                 # int -> konvertiert mit repr()
   record_property("tags", ["smoke", "api"])     # list -> konvertiert mit repr()
   assert 1 + 1 == 2

Attribute in test.guide (alle Werte als String):

Attribut

Wert

ecu_sw_version

v1.2.3

retries

2

tags

['smoke', 'api']

Argument-Aufzeichnung

Die Argumente jeder Testfunktion (einschließlich parametrisierter Werte und injizierter Fixtures) werden als test.guide-Parameter gemeldet. Dadurch können Sie einzelne Ausführungen eines parametrisierten Testfalls später filtern oder unterscheiden. Für jedes Testfallargument wird ein test.guide-Parameter mit der Richtung IN erstellt. Diese Funktion ist immer aktiv.

Info

Werte vom Typ str oder int werden unverändert verwendet. Alle anderen Python-Objekte werden in repr() konvertiert, damit komplexe Strukturen lesbar dargestellt werden.

Beispiel

import pytest

@pytest.mark.parametrize("x,y", [ (1, 2), (3, 4) ])
def test_params(x, y):
   assert (x + y) > 0

Ergebnis: Zwei gemeldete test.guide-Testfälle (mit gleichem Namen) mit den folgenden Parameterwerten:

Testlauf

x

y

1

1

2

2

3

4