Regressionstests mit dem Befehl "Run-Compare"

Der Befehl "PQTest run-compare " ist ein leistungsfähiges Tool für Regressionstests, mit dem Sie die Funktionen des Verbinders und die Generierung von Befehlstext gründlich auswerten können. Um die Vielseitigkeit zu veranschaulichen, bieten die nachfolgenden Abschnitte verschiedene Beispiele, die auf verschiedene Szenarien zugeschnitten sind.

Note

Der Befehl "Run-Compare " ersetzt den vorherigen Vergleichsbefehl .

Testen von Eingabeformaten

Der Befehl "Run-Compare " unterstützt zwei Testeingabeformate:

  • Ausdrucksformat: Ein einzelner M-Ausdruck (z. B. ein let Ausdruck oder Funktionsaufruf). Dieses Format ist das einfachste Format und eignet sich für die meisten Testszenarien.
  • Abschnittsdokumentformat: Ein M-Abschnittsdokument , das mindestens ein Abschnittsmitglied enthält. Dieses Format eignet sich für Tests, die Hilfsfunktionen, freigegebene Werte oder komplexere Setups erfordern.

Wenn eine Testdatei das Ausdrucksformat verwendet, konvertiert PQTest es automatisch intern in ein Abschnittsdokument vor der Auswertung. Sie können Ihre Testeingabe auch direkt als Abschnittsdokument schreiben.

Beispiel für ein Ausdrucksformat

let
    Source = Contoso.Contents("TestEndpoint"),
    Result = Table.RowCount(Source)
in
    Result

Beispiel für das Abschnittsdokumentformat

section Test;

shared Helper = (x) => x + 1;
shared Query = let
    Source = Contoso.Contents("TestEndpoint"),
    Result = Helper(Table.RowCount(Source))
in
    Result;

Wenn eine Parameterabfrage bereitgestellt wird, wird die Parameterabfrage als Abschnittselement zum Abschnittsdokument hinzugefügt. Die Parameterabfrage wird als Teil desselben Abschnitts ausgewertet, sodass die Testabfrage direkt darauf verweisen kann.

Grundlegende Abfragen

Die einfachste Form von Tests besteht darin, einer .query.pq Datei einen einzelnen Abfrageausdruck hinzuzufügen, den Sie mit dem Befehl "Ausführen vergleichen " ausführen können. PQTest wertet den Ausdruck aus und generiert eine .pqout (Ausgabe)-Datei mit demselben Namen. Bei nachfolgenden Läufen vergleicht sie die aus der Auswertung der .query.pq Datei generierte Ausgabe mit der .pqout Datei (Ausgabedatei) mit demselben Namen und gibt die Ausgabe der Auswertung zurück.

Beispiel 1: Ausführen des Befehls "Ausführen des Vergleichens" für eine Abfragedatei, wenn keine Ausgabedatei vorhanden ist

Im folgenden Beispiel wird eine einzelne Abfragetestdatei mithilfe der angegebenen Power Query-Erweiterung ausgeführt und ausgabedatei generiert, die verglichen werden soll.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq
[
  {
    "Details": "Contoso.Contents(\"TestEndpoint\")",
    "EndTime": "2025-12-11T18:04:14.8991822+00:00",
    "Method": "Compare.TestFiles",
    "Name": "contoso.query.pq",
    "StartTime": "2025-12-11T18:04:11.1532388+00:00",
    "Output": [
      {
        "SourceFilePath": "contoso.query.pq",
        "OutputFilePath": "contoso.query.pqout",
        "Status": "Output File Generated",
        "SerializedSource": null,
        "SourceError": null,
        "OutputError": null
      }
    ],
    "Status": "Passed",
    "Type": "PQTest.Expression"
  }
]

Beispiel 2: Den Befehl 'run-compare' für eine Abfragedatei ausführen, wenn keine Ausgabedatei vorhanden ist und der Schalter FailOnMissingOutputFile gesetzt ist.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq -fomof
[
  {
    "Details": "Contoso.Contents(\"TestEndpoint\")",
    "EndTime": "2025-12-11T18:04:14.8991822+00:00",
    "Method": "Compare.TestFiles",
    "Name": "contoso.query.pq",
    "StartTime": "2025-12-11T18:04:11.1532388+00:00",
    "Output": [
      {
        "SourceFilePath": "contoso.query.pq",
        "OutputFilePath": "contoso.query.pqout",
        "Status": "Missing Output File",
        "SerializedSource": "Output of contoso.query.pq",
        "SourceError": null,
        "OutputError": null
      }
    ],
    "Status": "Failed",
    "Type": "PQTest.Expression"
  }
]

Beispiel 3: Ausführen des Befehls 'run-compare' für eine Abfragedatei mit einer vorhandenen Ausgabedatei

Im folgenden Beispiel wird eine einzelne Abfragetestdatei mithilfe der angegebenen Power Query-Erweiterung ausgeführt, mit der Ausgabedatei verglichen und das Ergebnis zurückgegeben.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq
[
  {
    "Details": "Contoso.Contents(\"TestEndpoint\")",
    "EndTime": "2025-12-11T18:04:14.8991822+00:00",
    "Method": "Compare.TestFiles",
    "Name": "contoso.query.pq",
    "StartTime": "2025-12-11T18:04:11.1532388+00:00",
    "Output": [
      {
        "SourceFilePath": "contoso.query.pq",
        "OutputFilePath": "contoso.query.pqout",
        "Status": "Passed",
        "SerializedSource": null,
        "SourceError": null,
        "OutputError": null
      }
    ],
    "Status": "Passed",
    "Type": "PQTest.Expression"
  }
]

Testen mit Parameterabfrage

Die Parameterabfrage ist eine Abfrage, die mit einer Testabfrage zur Laufzeit kombiniert wird, wobei die Parameterabfrage zuerst ausgeführt wird. Mit dieser Funktion können Sie die Datei ".query.pq" in zwei Teile aufteilen: die Parameterabfragedatei und die Testabfragedatei.

Agnostische Datenquellentests mit Parameter- und Testabfrageformat

Ein Beispiel für einen Anwendungsfall, in dem diese Funktionalität nützlich wäre, besteht darin, eine agnostische Testsuite für Datenquellen zu erstellen. Sie können Ihre Parameterabfrage verwenden, um Daten aus der Datenquelle abzurufen und die Testabfrage generisch M zu haben. Wenn Sie die Tests für einen anderen Connector ausführen möchten, müssen Sie die Parameterabfrage nur hinzufügen/aktualisieren, um auf diese bestimmte Datenquelle zu verweisen.

Ein wichtiger Unterschied bei der Verwendung einer Parameterabfrage besteht darin, dass die Testabfrage einem anderen Format folgt. Anstatt ein Formelausdruck zu sein, muss es sich um eine M-Funktion handeln, die einen Eingabeparameter verwendet, der die von der Parameterabfrage zurückgegebene Tabelle darstellt.

Wenn eine Parameterabfrage bereitgestellt wird, wird die Parameterabfrage am Ende des Abschnittsdokuments des Tests als Abschnittselement hinzugefügt. Die Test- und Parametereingaben werden dann als einzelnes Mashup-Abschnittsdokument ausgewertet.

Note

Wenn die Parameterabfragedatei Fehler enthält (z. B. Syntaxfehler oder Auswertungsfehler), meldet PQTest einen beschreibenden Fehler, der das Problem mit der Parameterdatei angibt, anstatt einen unklaren Fehler zu erzeugen.

Angenommen, Sie haben die folgende Testabfrage:

let
    Source = Snowflake.Databases("...", "..."),
    Database = Source{[Name="...",Kind="Database"]}[Data],
    SelectColumns = Table.RemoveColumns(Database, { "Data" })
in
    SelectColumns

Um sie in eine Test- und Parameterabfrage zu konvertieren, müssen Sie sie wie folgt aufteilen:

Parameterabfrage:

let
    Source = Snowflake.Databases("...", "..."),
    Database = Source{[Name="...",Kind="Database"]}[Data],
    Schema = Database{[Name="...",Kind="Schema"]}[Data],
    Taxi_Table = Schema{[Name="...",Kind="Table"]}[Data]
in
    Taxi_Table

Testabfrage:

(Source) => let
    SelectColumns = Table.RemoveColumns(Source, { "VendorID" })
in
    SelectColumns

Beispiel 4: Verwenden von Parameterabfragen und Testabfragen mit run-compare-Befehl

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq -pa contoso.parameter.pq
[
  {
    "Details": "(Source) => let\r\n    Schemas = Table.RemoveColumns(Source, { \"Data\" })\r\nin\r\n    Schemas",
    "EndTime": "2025-12-11T18:04:14.8991822+00:00",
    "Method": "Compare.TestFiles",
    "Name": "contoso.query.pq",
    "StartTime": "2025-12-11T18:04:11.1532388+00:00",
    "Output": [
      {
        "SourceFilePath": "contoso.query.pq",
        "OutputFilePath": "contoso.query.pqout",
        "Status": "Passed",
        "SerializedSource": null,
        "SourceError": null,
        "OutputError": null
      }
    ],
    "Status": "Passed",
    "Type": "PQTest.Expression"
  }
]

Vergleich der Diagnose

Indem Sie einen Diagnosekanal abonnieren, können zusätzliche Diagnoseinformationen ausgewertet werden, wenn Sie den Befehl "run-compare" verwenden. Wenn der Befehl " Run-Compare " ausgeführt wird, gibt PQTest eine .diagnostics Datei für jeden abonnierten Kanal mit einem Ereignis aus. Bei nachfolgenden Ausführungen vergleicht es das Diagnoseereignis mit seiner .diagnostics Datei, ähnlich wie .pqout.

Beispiel 5: Abonnieren des ODBC-Diagnosekanals (Open Database Connectivity), um das Query Folding zu überprüfen

Das folgende Beispiel zeigt, wie Sie den ODBC-Kanal abonnieren, der den gesamten vom ODBC-Treiber generierte SQL-Code erfasst, wenn Query Folding verwendet wird.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq -dc "Odbc"

Der ODBC-Diagnosekanal kann verwendet werden, um zu überprüfen, ob eine Abfrage gefaltet wird und dass sie das richtige SQL generiert.

let
    Source = AzureSpark.Tables("..."),
    T1 = Source{[Schema="default",Item="DATABASE"]}[Data],
    SelectColumns = Table.Group(T1, {}, {{"Maximum", each List.Max([number_column]), type number}}),
    FirstN = Table.FirstN(SelectColumns, 1)
in
    FirstN

Die Abfrage wird nun gefaltet und generiert den folgenden ODBC-Befehlstext in der .diagnostics Datei:

[
  {
    "Command": "DESCRIBE default.DATABASE;"
  },
  {
    "Command": "select top 1 max(`number_column`) as `C1` from `SPARK`.`default`.`DATABASE`"
  }
]

Verwenden einer Einstellungsdatei

Jeder Befehlszeileneingabeparameter für den Befehl "Run-Compare " kann auch über eine JSON-Einstellungsdatei übergeben werden. Der JSON-Code kann die folgenden Optionen haben:

Auswahl Typ Beschreibung
ExtensionPaths Array Array von Pfaden, die auf die Connectordatei verweisen (mez/pqx).
FailOnMissingOutputFile bool Beim Vergleichslauf wird keine PQOut-Datei erzeugt, und der Prozess schlägt fehl, wenn die Datei nicht vorhanden ist.
FailOnFoldingFailure bool Fehler beim Ausführen des Vergleichs, wenn eine Abfrage nicht vollständig gefaltet wird. Wenn diese Option aktiviert ist, lösen Abfragen, die nicht vollständig in die Datenquelle gefaltet werden können, einen Fehler aus, anstatt auf die lokale Auswertung zurückzufallen.
ParameterQueryFilePath Schnur Abfragedatei, die M-Ausdrücke enthält, die zur Laufzeit mit der Testabfragedatei kombiniert werden. Ein gängiger Anwendungsfall besteht darin, eine einzelne Parameterabfragedatei zum Angeben eines M-Ausdrucks zum Abrufen der Daten für mehrere Testabfragen zu verwenden.
QueryFilePath Schnur Abfragedatei, die M-Ausdruck (.pq) enthält, der getestet werden soll.
TrxReportPath Schnur Generiert eine TRX (Visual Studio Test Results File) Ergebnisdatei und separate JSON-Dateien für jeden Test in einem bestimmten Pfad.
DiagnosticChannels Array Name der Diagnosekanäle, die an die Testausführung angeschlossen werden sollen (z. B. Odbc zum Erfassen von Abfragefaltungsanweisungen).
Zwischenergebnistestordner Schnur Benutzerdefinierter Ordnerpfad zum Speichern von Zwischentestergebnissen.
ZwischenergebnisseSpeichern bool Hält Zwischentestergebnisse nach Abschluss der Testausführung bei.

Wenn sowohl die Befehlszeileneingabe als auch die Einstellungsoption bereitgestellt werden, wird die Befehlszeileneingabe priorisiert.

Beispiel 6: Verwenden der Einstellungsdatei anstelle von Befehlszeilenargumenten

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q contoso.query.pq -fomof

Der Befehl entspricht dem folgenden Befehl:

<Path to PQTest.exe>.\PQTest.exe run-compare -sf settings.json

Dabei ist settings.json die folgende JSON-Datei:

{
  "ExtensionPaths": ["contoso.mez"],
  "QueryFilePath": "contoso.query.pq",
  "FailOnMissingOutputFile": true
}

Testen von Batterien mit Run-Compare-Befehl

Eine Testbatterie ist eine Sammlung von Tests, die mehrere Aspekte Ihres Codes auswerten. Platzieren Sie die Abfragedateien im selben Ordner, damit PQTest sie problemlos finden kann. Geben Sie anstelle eines bestimmten Testdateinamens den Ordnerpfad an, und PQTest führt alle .query.pq-Testabfragedateien in einem einzigen Durchgang aus.

Beispiel 7 : Ausführen einer Batterie von Tests

Angenommen, ein Ordner mit dem Namen "Test", der die folgenden Dateien enthält:

  • contoso.testa.query.pq
  • contoso.testb.query.pq
  • contoso.testc.query.pq

Die gesamte Testbatterie kann über die folgende Kommandozeile ausgeführt werden.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test

Ignorieren von Tests beim Ausführen einer Reihe von Tests

Ein Test kann ausgelassen werden, wenn eine Reihe von Tests durchgeführt wird, indem die Dateierweiterung der Datei .query.pq in .query.pq.ignore geändert wird.

Beispiel 8 – Ignorieren eines Tests beim Ausführen einer Testbatterie

Angenommen, ein Ordner mit dem Namen "Test", der die folgenden Dateien enthält:

  • contoso.testa.query.pq
  • contoso.testb.query.pq.ignore
  • contoso.testc.query.pq

Die Dateien "contoso.testa.query.pq" und "contoso.testc.query.pq" werden ausgeführt, aber "contoso.testb.query.pq.ignore" wird ignoriert, wenn der folgende Befehl ausgeführt wird, um die Testbatterie auszuführen.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test

Filtertests

Die --testFilter Option ermöglicht es Ihnen, Testdateien selektiv einzuschließen oder auszuschließen, wenn Testbatterien ausgeführt werden. Bei dieser Option werden Globmuster verwendet, um Dateipfade abzugleichen und können mehrmals angegeben werden, um komplexe Filterregeln zu erstellen.

Inklusionsfilter

Geben Sie an, welche Dateien in die Testausführung aufgenommen werden sollen, indem Sie Standard-Glob-Muster verwenden.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test --testFilter "Suite1/**/*.pq"

Ausschlussfilter

Geben Sie an, welche Dateien aus der Testausführung ausgeschlossen werden sollen, indem Sie das ! Präfix verwenden, um Ausschlussmuster anzugeben.

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test --testFilter "!BrokenTests/*"

Mehrere Filter

Mehrere --testFilter Optionen können kombiniert werden, um komplexe Filterlogik zu erstellen:

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test --testFilter "**/*.pq" --testFilter "!BrokenTests/*" --testFilter "!**/*donotrun*.pq"

Filterverhalten

  • Implizite Inklusion: Wenn keine Einschlussfilter angegeben werden, **/*.query.pq wird automatisch angewendet.
  • Groß-/Kleinschreibung wird nicht beachtet: Bei allen Mustern wird die Groß-/Kleinschreibung nicht beachtet.
  • Reihenfolge unabhängig: Die Reihenfolge der Filter wirkt sich nicht auf das Ergebnis aus.
  • Pfadformat: Verwenden Von Schrägstrichen (/) in Mustern für plattformübergreifende Kompatibilität.

Glob-Musterbeispiele

Pattern Beschreibung
**/*.pq Alle .pq Dateien in einem beliebigen Verzeichnis
**/*.query.pq Alle .query.pq Dateien in einem beliebigen Verzeichnis
Suite1/**/*.pq Alle .pq Dateien unter Suite1-Verzeichnis
**/test*.pq Alle .pq Dateien beginnend mit "test"
!BrokenTests/* Alle Dateien im Verzeichnis BrokenTests ausschließen
!**/*temp*.pq Ausschließen aller .pq Dateien mit "temp"
SpecificTest.pq Nur die bestimmte Datei einschließen

Note

Filter gelten für den relativen Pfad aus dem angegebenen Abfrageverzeichnis. Wenn Filter bereitgestellt werden und der Abfragedateipfad auf eine bestimmte Datei anstatt auf ein Verzeichnis verweist, wird ein Fehler zurückgegeben. Verwenden Sie Anführungszeichen um Muster herum, um die automatische Erweiterung der Shell zu verhindern.

Auflistung von Testdateien ohne Ausführung

Mit der --listOnly-Option können Sie eine Vorschau darauf anzeigen, welche Testdateien durch den run-compare-Befehl ausgeführt werden würden, ohne die Tests tatsächlich auszuführen. Diese Option ist nützlich, um das Testerkennungs- und das Filterverhalten zu überprüfen.

Beispiel 9 – Auflisten von Testdateien

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test --listOnly
{
    "SourcePath": "C:\\MyProject\\test",
    "TestFilters": [],
    "Tests": [
        {
            "Test": "MyTest.query.pq",
            "RelativePath": "Suite1\\MyTest.query.pq",
            "AbsolutePath": "C:\\MyProject\\test\\Suite1\\MyTest.query.pq"
        },
        {
            "Test": "AnotherTest.query.pq",
            "RelativePath": "Suite2\\AnotherTest.query.pq",
            "AbsolutePath": "C:\\MyProject\\test\\Suite2\\AnotherTest.query.pq"
        }
    ]
}

Die Ausgabe enthält die folgenden Felder:

  • SourcePath: Der QueryFilePath-Wert, der für den Befehl bereitgestellt wurde (von -q option).
  • TestFilters: Eine Liste aller TestFilter-Werte, die angewendet wurden (aus --testFilter Optionen).
  • Tests: Ein Array von Testdateiobjekten, wobei jedes Objekt Folgendes enthält:
    • Test: Der Dateiname der Testdatei.
    • RelativePath: Der Pfad relativ zu dem Basistestverzeichnis, das durch -q angegeben wird.
    • AbsolutePath: Der vollständige absolute Pfad zur Testdatei.

Kombinieren mit Testfiltern

Die --listOnly Option berücksichtigt alle --testFilter Optionen, sodass Sie eine Vorschau der Auswirkungen Ihrer Filter anzeigen können:

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test --testFilter "Suite1/**/*.pq" --listOnly

Note

Alle Testfilter werden vor der Auflistung angewendet. Bei Verwendung von --listOnly erfolgt keine tatsächliche Testausführung.

Verwalten von Zwischentestergebnissen

Der Befehl run-compare generiert Zwischendateien während der Testausführung, einschließlich tatsächlicher Testausgabedateien (.pqout) und Diagnosedateien (.diagnostics). Standardmäßig werden diese Dateien an einem temporären Speicherort mit einer datumsbasierten Unterordnerstruktur erstellt und nach Abschluss der Testausführung automatisch bereinigt.

Sie können dieses Verhalten mit zwei Optionen steuern:

  • --intermediateTestResultsFolder | -itrf: Gibt einen benutzerdefinierten Ordnerpfad zum Speichern von Zwischentestergebnissen an.
  • --persistIntermediateTestResults | -pitr: Behält die Zwischenergebnisse nach Abschluss der Testausführung bei.

Beispiel 10 : Verwenden eines benutzerdefinierten Zwischenordners und beibehaltener Ergebnisse

<Path to PQTest.exe>.\PQTest.exe run-compare -e contoso.mez -q .\test -itrf "C:\TestResults" -pitr

Zwischenordnerstruktur

Wenn Sie einen Zwischentestergebnisordner angeben, erstellt PQTest eine datumsbasierte Unterordnerstruktur, um Testergebnisse zu organisieren:

<IntermediateTestResultsFolder>\
  └── YYYYMMDD_HHmmss_ffffff\
      ├── Test1.query.pqout
      ├── Test2.query.pqout
      ├── Test3.query.odbc.diagnostics
      └── ...

Bereinigungsverhalten

Das Bereinigungsverhalten hängt davon ab, ob Sie einen Zwischenordner angeben und ob Sie das Permanent-Flag verwenden:

Szenario Zwischenordner angegeben Kennzeichnung beibehalten Behavior
1 Nein Nein Dateien, die am temporären Speicherort erstellt wurden, datumsbasierte Unterordner nach Tests gelöscht
2 Yes Nein Dateien, die im angegebenen Ordner erstellt wurden, datumsbasierte Unterordner nach Tests gelöscht
3 Nein Yes Dateien, die am temporären Speicherort erstellt wurden, datumsbasierte Unterordner nach Tests gelöscht
4 Yes Yes Dateibasierte Unterordner im angegebenen Ordner erstellt, datumsbasierten Unterordner beibehalten

Note

Um Zwischenergebnisse beizubehalten, müssen Sie sowohl --intermediateTestResultsFolder als auch --persistIntermediateTestResults angeben. Das --persistIntermediateTestResults Kennzeichen allein ohne Angabe eines Ordners behält keine Ergebnisse bei. Wenn der angegebene Zwischenordner nicht vorhanden ist, versucht PQTest, ihn zu erstellen. Relative Pfade werden unterstützt und werden relativ zum aktuellen Arbeitsverzeichnis aufgelöst.