2 Punkte von GN⁺ 2023-07-01 | 1 Kommentare | Auf WhatsApp teilen
  • Hurl 4.0.0 ist eine neue Version des curl-basierten CLI-HTTP-Testtools und verbessert den Ablauf für die Ausführung von HTTP-Anfragen und die Prüfung von Antworten, die in einfachen Textdateien beschrieben sind
  • HTML-Reports werden als reines HTML nur mit Inline-CSS und ohne JavaScript erzeugt und zeigen pro Anfrage/Antwort eine Waterfall-Zeitleiste, Ausführungslogs und Inline-Fehler
  • --error-format long gibt die Response-Header und den Body fehlgeschlagener Tests aus, sodass sich beim CI/CD-Debugging der nötige Kontext zur Ursachenanalyse ohne erneuten Lauf erfassen lässt
  • Mit den neuen Filtern decode und xpath lassen sich Response-Bytes mit unklarem Zeichensatz direkt dekodieren und XPath-Prüfungen auf Teilen von HTML ausführen
  • Teile der JSONPath-Auswertung haben sich geändert, und benutzerdefinierte HTTP-Methoden in Großbuchstaben werden unterstützt, sodass sich auch neue Methoden wie QUERY ausprobieren lassen

Überblick über Hurl 4.0.0

  • Hurl ist ein auf curl basierendes Kommandozeilen-Tool, das HTTP-Anfragen ausführt, die in einem einfachen Klartextformat definiert sind
  • In Hurl-Dateien lassen sich Anfragen, erwartete HTTP-Statuswerte sowie Assertions wie Header, Zertifikate und JSONPath gemeinsam festhalten
  • Hurl 4.0.0 bringt vor allem Änderungen bei HTML-Reports, Fehlerausgabe, Filtern, dem JSONPath-Verhalten und der Unterstützung benutzerdefinierter HTTP-Methoden

HTML-Reports und Waterfall-Zeitleiste

  • Der Hurl HTML report erzeugt pro Ausführung drei Arten von Informationen
    • Waterfall-Zeitleiste: Stellt jede Anfrage/Antwort grafisch dar und zeigt Antwort-Timings wie DNS, TCP-Handshake und Time to First Byte
    • Ausführungslog: Enthält unter anderem Request-/Response-Header und Zertifikatsinformationen
    • Quellcodedatei mit Syntax-Highlighting: Zeigt Fehler inline an
  • Der Report besteht ohne JavaScript aus reinem HTML und Inline-CSS und lässt sich daher leicht in CI/CD-Umgebungen wie GitLab CI/CD oder GitHub Actions integrieren
  • Die in der Waterfall-Zeitleiste verwendeten Timings stammen von libcurl und werden auch über die --json-Option offengelegt
    • --json liefert strukturierte Ausführungsinformationen inklusive Fehlern, Assertions, Zertifikaten, Captures, Cookies und Timings
    • Auf Basis dieser JSON-Ausgabe lassen sich eigene Reports erstellen

Durch Visualisierung sichtbar gewordener Assertion-Performance-Engpass

  • Umfangreiche Visualisierung kann verborgene Performance-Probleme sichtbar machen
  • In einigen Läufen traten große Abstände zwischen Anfragen auf; die Ursache war eine sehr hohe Zahl von Assertions auf HTTP-Responses
  • Die Berechnung von Assertions funktioniert in Hurl 4.0.0 derzeit auf einfache Weise
    • Jede Assertion derselben Response wird unabhängig verarbeitet
    • Für jede Assertion wird von vorn geparst und neu ausgewertet
  • Das Hurl-Team war mit der Kombination aus libcurl und Rust zwar von der Geschwindigkeit überzeugt, kam durch diesen Fall aber zu dem Schluss, dass im nächsten Release Verbesserungen bei der Assertion-Performance nötig sind

Detaillierte Fehlerausgabe für CI/CD

  • Die bisherige Ausgabe bei Testfehlern war stark auf den Erwartungswert fokussiert und konnte für die Analyse zu wenig Informationen enthalten
  • Mit der neuen --error-format-Option lässt sich eine ausführlichere Fehlerbeschreibung wählen
  • Im Modus --error-format long werden Response-Header und Response-Body automatisch im Log ausgegeben
  • Im Beispiel suchte der Test nach dem Header Control-Security-Policy, tatsächlich war in der Response jedoch Content-Security-Policy enthalten
    • Weil Response-Header und Body im Log enthalten sind, lässt sich ein solcher Tippfehler leicht erkennen
  • Die Option ist besonders in CI/CD-Umgebungen nützlich, wenn man den für das Session-Debugging nötigen Kontext erhalten möchte, ohne den Test erneut auszuführen
  • Da auch der Response-Body protokolliert wird, können Logs sehr lang werden

Neue Filter: decode und xpath

  • Text-Assertions in Hurl dekodieren die Bytes eines Response-Bodys automatisch und nutzen dabei den charset-Hinweis aus dem Content-Type-Response-Header
  • Es gibt jedoch Fälle ohne Kodierungsangabe in Content-Type oder mit einem Zeichensatz, der im HTML-Dokument selbst per <meta>-Tag angegeben ist
  • Der neue decode-Filter ermöglicht es, Bytes explizit in Text zu dekodieren und dann zu prüfen
    • Im Beispiel wird ein mit GB2312 kodierter Body mit bytes decode "gb2312" dekodiert
  • Der neue xpath-Filter erlaubt die Auswertung von XPath-Ausdrücken auf Teilen einer Response
    • Im Beispiel wird mit xpath "string(//body)" der Text des HTML-body geprüft

Änderungen bei der JSONPath-Auswertung

  • Hurl 4.0.0 ändert Teile der Auswertung von JSONPath-Abfragen
  • Für JSONPath gibt es keine wirklich passende offizielle Spezifikation, und Hurl versucht, sich so eng wie möglich an das de-facto-standardisierte Dokument von goessner.net zu halten
  • Je nach Implementierung gibt es unterschiedliche Edge Cases
    • Standard-JSONPath liefert immer Collections zurück, was oft wenig aussagekräftig ist und Tests erschweren kann
    • Manche Implementierungen unterscheiden zwischen dem Knotenwert eines definite path und der Collection eines indefinite path
  • In Hurl 4.0.0 gibt es nur zwei Arten von Selektoren, die Werte direkt zurückgeben
    • Array-Index-Selektor: $.store.book[2]
    • Objekt-Key-Selektor: $.store.bicycle.color, $.store.bicycle['color']
  • Selektoren mit Filtern oder Selektoren wie $[*].id geben Collections zurück
    • Um aus einer Collection einen Wert zu entnehmen, kann der nth-Filter verwendet werden

Benutzerdefinierte HTTP-Methoden

  • Hurl 4.0.0 unterstützt beliebige benutzerdefinierte HTTP-Methoden
  • Methoden müssen in Großbuchstaben geschrieben werden
  • So lässt sich etwa die neu entstehende Methode QUERY direkt ausprobieren

Release Notes und Bitte um Mitwirkung

  • Weitere Verbesserungen und Fehlerbehebungen finden sich in den Release Notes
  • Das Projekt bittet um GitHub-Stars, das Teilen auf Twitter, Vorschläge für Verbesserungen und das Teilen von Praxisbeispielen

1 Kommentare

 
GN⁺ 2023-07-01
Hacker-News-Kommentare
  • Mir gefiel, dass die Einführung zu Hurl mit „ein curl-basierendes Kommandozeilen-Tool, das HTTP-Anfragen ausführt, die in einem einfachen Plain-Text-Format definiert sind“ begann.
    Ich habe Hurl zum ersten Mal gesehen, aber schon die kurze Einführung und das Codebeispiel ganz oben haben gereicht, damit ich es sofort installieren und ausprobieren wollte; wirkt wie ein großartiges Release.

    • Als Hurl-Maintainer habe ich nach langem Mitlesen bei Hacker News alle möglichen Präsentationshinweise notiert, etwa „zeige Sprachbeispiele so früh wie möglich“ und „erkläre das Konzept jedes Mal knapp“, und ich wollte das tatsächlich auf hurl.dev umsetzen.
    • Zu viele Ankündigungen und READMEs fangen mit Installationsanforderungen oder „wir haben X, Y und Z behoben“ an und sagen dabei nicht einmal, was das Tool eigentlich macht; dieser Ansatz ist der richtige.
    • Stimmt, aber das meiste davon hätte schon im Titel stehen sollen.
      Etwa ein Titel wie Hurl: Run HTTP requests in a simple plain-text format wäre besser gewesen.
  • Ich wünschte, man würde das zum Industriestandard für API-Tests machen.
    Ich bin es leid, mir Postman-Screenshots vom QA-Team anzusehen und nach Änderungen darauf zu warten, dass QA auf Send klickt; und QA ist es vermutlich ebenso leid, auf Entwickler zu warten.
    Hurl können sowohl Entwickler als auch QA lesen und schreiben, es lässt sich automatisieren und in CI integrieren, erwartetes Verhalten lässt sich leicht weitergeben, und man kann es direkt in einen PR legen und als Ausgangspunkt für QA verwenden — wo es möglich ist, gibt es scheinbar keinen Grund, es nicht zu nutzen.

    • Ich nutze Hurl in einem Service sowohl für manuelle API-Tests als auch in CI, und es ist ziemlich gut.
      Man kann den Ablauf von HTTP-Austauschen pro Workflow in einer einzigen hurl-Datei ablegen, und daraus wird eine Testsuite, die direkt in Git passt.
    • Wenn ihr ein Team seid, das VSCode nutzt, könnt ihr auch vscode-restclient ausprobieren: https://github.com/Huachao/vscode-restclient
      Hurl ist allerdings ebenfalls sehr interessant, und ich stimme zu, dass die Unabhängigkeit vom Editor für dieses Problem die bessere Lösung ist.
    • Mich würde interessieren, ob du auch https://k6.io/ ausprobiert hast.
      Damit kann man Last-/Performance-Tests in JS schreiben und ins Repository committen, sie leicht in CI automatisieren, Metriken an verschiedene Backends senden, neben HTTP auch andere Protokolle nutzen und erhält eine moderne Kommandozeilenoberfläche mit vielen Funktionen.
      Es gibt auch einen Postman-zu-k6-Konverter: https://github.com/apideck-libraries/postman-to-k6
      Die Philosophie von k6 ist, dass Entwickler solche Tests wie Unit-/Integrationstests schreiben und so den klassischen QA-Entwickler-Zyklus durchbrechen; Hurl sieht ebenfalls gut aus, ist funktional aber stärker eingeschränkt als bestehende Performance-Test-Tools, und persönlich bevorzuge ich es, Tests in einer Programmiersprache statt in einem speziellen Textformat zu schreiben.
    • Persönlich mag ich den Ansatz, erst mit OpenAPI zu definieren und dann die Spezifikation mit Dredd zu validieren.
      Selbst wenn man Tools verwendet, die die Spezifikation aus dem Quellcode erzeugen, sind Benutzerfehler bei der Definition von Endpoint-Metadaten weiterhin möglich, und Dredd fängt das ab.
  • Das ist fast das beste Beispiel für ein modernes Unix-Programm, das ich bisher gesehen habe.
    Es liest von stdin, schreibt nach stdout, hinterlässt nicht überall im Terminal Unicode-Emojis, und die man-Pages sind ebenfalls ziemlich gut.
    Ich mag auch, dass die Dateiendung von hurl vier statt drei Zeichen hat; anscheinend sind wir endlich die Sorge um MS-DOS-Kompatibilität los.
    Sieht nach einem Tool aus, das man ernsthaft verwenden kann.

    • Mir war gar nicht klar, wie störend Emojis im Terminal für mich geworden sind, aber als ich gelesen habe, dass dieses Tool keine hat, war ich plötzlich erfreut.
    • Nicht nur MS-DOS-, sondern auch VMS-Kompatibilitätssorgen sind wir damit offenbar los.
  • Für HTTP-Verarbeitung auf der Kommandozeile mag ich Httpie oder die schnellere Rust-Neuimplementierung XH am liebsten.
    Man kann von der Kommandozeile aus mit einer Syntax, die HTTP viel näher ist als curl, Requests senden, ohne viele Optionen lernen zu müssen.
    Wenn man sich bereits mit curl auskennt, bringt das vielleicht nicht viel, aber für den gelegentlichen Einsatz ist es deutlich intuitiver.
    https://httpie.io/
    https://github.com/ducaale/xh

  • Bei Adaptive nutzen wir hurl.dev umfangreich für Testautomatisierung: https://adaptive.live
    Wir testen unseren gesamten internen Produktfluss mit Hurl, und im Hinblick auf Produktstabilität war es eine der besten Entscheidungen, die wir in der Organisation eingeführt haben.
    Vor jedem Deployment führen wir mehrere Hurl-basierte automatisierte Tests für Onboarding, Registrierung, Kernabläufe usw. aus, und da sie containerisiert sind, können sie auch parallel laufen.
    Wir bauen außerdem interne Tools rund um hurl.dev und mögen, dass es leicht zu lernen ist, sodass auch Analysten oder Business-User Tests erstellen können.

    • Mich würde interessieren, warum ihr ein eigenständiges Tool verwendet.
      Im Testkontext wirkt ein browserbasierter Ansatz wie mit Selenium viel mächtiger und insgesamt nützlicher.
    • Mich würde interessieren, ob OAuth-Flows standardmäßig unterstützt werden oder ob man fest kodierte Tokens braucht.
      Ich habe in der Dokumentation nachgesehen, aber dazu nichts gefunden.
  • Ich beobachte hurl schon eine Weile, und der Unterschied zu anderen Tools scheint mir zu sein, dass es eine eigene DSL zum Testen hat.
    Es schickt nicht nur HTTP-Requests, sondern kann auch Responses validieren und Daten erfassen.
    Falls der Maintainer mitliest: Es wäre schön, wenn man Validierung an externe Skripte auslagern könnte.
    Wenn man zum Beispiel prüfen will, ob alle Eigenschaften einer Item-Sammlung denselben Wert haben, ist das ohne den nth-Selektor noch schwierig, und so etwas wie nth = * wäre ebenfalls nötig.
    Alle Anwendungsfälle in der DSL abzubilden ist eine zu große Aufgabe; es wäre daher gut, wenn man jsonpath-Ergebnisse an jq weitergeben und den Test bestehen lassen könnte, wenn true zurückkommt.

    • Eine DSL wächst am Ende zwangsläufig langsam zu einer turing-vollständigen Allzwecksprache heran, daher wirkt das Aufrufen externer Skripte vernünftig.
      Allerdings würden die Dateien dadurch weniger eigenständig, was wiederum einige ziemlich komplexe Probleme mit sich bringen könnte.
  • Hurl scheint schnell zu wachsen, was gut aussieht.
    Für Endpoint-Tests braucht man immer Authentifizierung; mich würde interessieren, ob es eine Möglichkeit gibt, die Authentifizierung in einer Datei zu definieren und sie am Anfang anderer Dateien zu laden, die ein Token benötigen.

    • Hurl scheint keine Funktionen wie include oder Makros zu haben.
      Es ist ohnehin fraglich, ob das überhaupt der beste Weg wäre, Geheimnisse zu speichern und zu verwenden.
      Laut Dokumentation kann man Variablen über Kommandozeilenargumente und Umgebungsvariablen an hurl-Dateien übergeben: https://hurl.dev/docs/templates.html
  • Für diesen Zweck gefällt mir auch httpyac ziemlich gut: https://httpyac.github.io
    Es hat JS-Scripting-Funktionen und ist damit ziemlich ähnlich, und nicht nur die Kommandozeilenoberfläche, sondern auch die VS-Code-Integration ist hervorragend.

    • httpyac ist auch gut mit der .http-Unterstützung in JetBrains-IDEs kompatibel.
      JetBrains bietet zudem ein kostenloses Kommandozeilen-Tool an, das aus .http-Dateien jUnit-Testreports erzeugt.
  • Ich habe erfahren, dass auch Visual Studio 2022 mit .http-Dateien ähnliche Funktionen unterstützt: https://learn.microsoft.com/en-us/aspnet/core/test/http-file...
    Hurl scheint allerdings deutlich mehr Funktionen zu haben.

    • Auch JetBrains-IDEs unterstützen das, daher wirkt es derzeit eher wie ein quasi standardnahes Format als andere Ansätze.
    • Hurl ist viel schneller.
    • Ich benutze seit einiger Zeit die VS-Code-Erweiterung, auf der diese Funktion basiert.