Gatling vs JMeter vs The Grinder: Lasttest-Tools vergleichen

1. Einleitung

Die Wahl des richtigen Werkzeugs für den Job kann entmutigend sein. In diesem Lernprogramm vereinfachen wir dies durch den Vergleich der drei Testtools für Webanwendungen - Apache JMeter, Gatling und The Grinder - mit einer einfachen REST-API.

2. Laden Sie die Testwerkzeuge

Lassen Sie uns zunächst kurz auf einige Hintergründe eingehen.

2.1. Gatling

Gatling ist ein Lasttest-Tool, das Testskripts in Scala erstellt. ** Der Recorder von Gatling generiert die Scala-Testskripte, eine Schlüsselfunktion für Gatling.

2.2. JMeter

JMeter ist ein Lasttest-Tool von Apache. Es bietet eine schöne GUI, die wir zur Konfiguration verwenden können. Eine einzigartige Funktion, genannt Logik-Controller, bietet große Flexibilität beim Einrichten von Tests in der GUI.

Besuchen Sie unser Intro to JMeter Tutorial mit Screenshots und weiteren Erläuterungen.

2.3. Der Schleifer

Und unser letztes Tool, The Grinder , bietet eine mehr programmierungsbasierte Skript-Engine als die anderen beiden und verwendet Jython. The Grinder 3 bietet jedoch Funktionen zum Aufzeichnen von Skripts.

Der Grinder unterscheidet sich auch von den beiden anderen Tools, indem er Konsolen- und Agentenprozesse zulässt. Diese Funktionalität bietet die Möglichkeit für einen Agentenprozess, sodass die Auslastungstests auf mehrere Server übertragen werden können. ** Es wird speziell als Lasttest-Tool angekündigt, mit dem Entwickler Deadlocks und Verzögerungen finden können.

3. Testfall-Setup

Als nächstes benötigen wir für unseren Test eine API. Unsere API-Funktionalität umfasst:

  • Einen Belohnungsdatensatz hinzufügen/aktualisieren

  • Eine/alle Belohnungsaufzeichnungen anzeigen

  • Verknüpfen Sie eine Transaktion mit einem Kundenbelohnungssatz

  • Transaktionen für einen Kundenbelohnungssatz anzeigen

  • Unser Szenario: **

Ein Geschäft hat einen landesweiten Verkauf mit neuen und wiederkehrenden Kunden, die Kundenboni benötigen, um Einsparungen zu erzielen. Die Prämien-API prüft das Kundenprämienkonto anhand der Kundennummer _. _ Wenn kein Prämienkonto vorhanden ist, fügen Sie es hinzu und verknüpfen Sie es mit der Transaktion.

Danach fragen wir die Transaktionen ab.

3.1. Unsere REST API

Lassen Sie uns einen kurzen Überblick über die API erhalten, indem Sie einige der Methodenstubs anzeigen:

@PostMapping(path="/rewards/add")
public @ResponseBody RewardsAccount addRewardsAcount(@RequestBody RewardsAccount body)

@GetMapping(path="/rewards/find/{customerId}")
public @ResponseBody Optional<RewardsAccount> findCustomer(@PathVariable Integer customerId)

@PostMapping(path="/transactions/add")
public @ResponseBody Transaction addTransaction(@RequestBody Transaction transaction)

@GetMapping(path="/transactions/findAll/{rewardId}")
public @ResponseBody Iterable<Transaction> findTransactions(@PathVariable Integer rewardId)

Beachten Sie einige Beziehungen, z. B. Abfragen nach Transaktionen anhand der Prämien-ID und Abrufen des Prämienkontos nach Kundennummer __ __Diese Beziehungen erzwingen Logik und Antwortanalyse für unsere Testszenarioerstellung.

  • Zum Glück gehen alle unsere Werkzeuge gut damit aus, manche besser als andere. **

3.2. Unser Testplan

Als nächstes brauchen wir Testskripte.

Um einen fairen Vergleich zu erhalten, führen wir für jedes Werkzeug die gleichen Automatisierungsschritte durch:

  1. Generieren Sie zufällige Kundenkonto-IDs

  2. Eine Transaktion buchen

  3. Analysieren Sie die Antwort nach der zufälligen Kunden-ID und der Transaktions-ID

  4. Abfrage einer Kundenbelohnungskonto-ID mit der Kunden-ID

  5. Analysieren Sie die Antwort für die Belohnungskonto-ID

  6. Wenn keine Belohnungskonto-ID vorhanden ist, fügen Sie eine mit einem Beitrag hinzu

  7. Buchen Sie dieselbe Anfangstransaktion mit der aktualisierten Belohnungs-ID mithilfe der

Transaktions-ID . Abfrage aller Transaktionen nach Belohnungskonto-ID

Sehen wir uns Schritt 4 für jedes Werkzeug genauer an. Stellen Sie außerdem sicher, dass Sie https://github.com/eugenp/tutorials/tree/master/testing-modules/load-testing-comparison/src/main/resources/scripts in der Stichprobe für alle drei abgeschlossenen Skripts lesen.

3.3. Gatling

Die Bekanntheit von Scala ist für Gatling ein großer Vorteil für Entwickler, da die Gatling-API robust ist und viele Funktionen enthält.

Die API von Gatling verwendet einen Builder-DSL-Ansatz, wie wir in Schritt 4 sehen können

.exec(http("get__reward")
  .get("/rewards/find/${custId}")
  .check(jsonPath("$.id").saveAs("rwdId")))
.pause(1)

Besonders hervorzuheben ist die Unterstützung von Gatling für JSON Path, wenn eine HTTP-Antwort gelesen und überprüft werden muss. Hier holen wir die Belohnungs-ID ab und speichern sie im internen Zustand von Gatling. Beachten Sie die Pause von einer Sekunde. Diese notwendige Prüfung verhindert, dass die nächste abhängige Anforderung fehlschlägt. Der check -Aufruf und saveAs blockierten nachfolgende exec -Anforderungen nicht.

Die Ausdruckssprache von Gatling erleichtert außerdem den dynamischen Text der Anforderung Strings:

.body(StringBody(
  """{
    "customerRewardsId":"${rwdId}",
    "customerId":"${custId}",
    "transactionDate":"${txtDate}"
  }""")).asJson)

Zum Schluss noch unsere Konfiguration für diesen Vergleich. Die 10 Läufe werden als Wiederholung des gesamten Szenarios festgelegt. __AtOnceUsers __method setzt die Threads/Benutzer:

val scn = scenario("RewardsScenario")
  .repeat(10) {
  ...
  }
  setUp(
    scn.inject(atOnceUsers(100))
  ).protocols(httpProtocol)

Das entire Scala-Skript kann in unserem Github-Repo angesehen werden.

3.4. JMeter

  • JMeter generiert nach der GUI-Konfiguration eine XML-Datei. ** Die Datei enthält JMeter-spezifische Objekte mit gesetzten Eigenschaften und deren Werten. Beispiel:

<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Add Transaction" enabled="true">
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="Transaction Id Extractor" enabled="true">

Überprüfen Sie die testname -Attribute. Sie können gekennzeichnet werden, wenn Sie sie mit den oben angegebenen logischen Schritten übereinstimmen. Die Möglichkeit, untergeordnete Elemente, Variablen und Abhängigkeitsschritte hinzuzufügen, gibt JMeter Flexibilität, da Scripting dies ermöglicht. Darüber hinaus legen wir sogar den Spielraum für unsere Variablen fest!

Unsere Konfiguration für Läufe und Benutzer in JMeter verwendet ThreadGroups und einen LoopController :

<stringProp name="LoopController.loops">10</stringProp>
<stringProp name="ThreadGroup.num__threads">100</stringProp>

Ansicht der gesamten jmx -Datei als Referenz . Das Schreiben von Tests in XML als .jmx -Dateien ist zwar möglich, macht aber bei einer voll funktionsfähigen Benutzeroberfläche keinen Sinn.

3.5. Der Schleifer

Ohne die funktionale Programmierung von Scala und GUI sieht unser Jython-Skript für The Grinder ziemlich einfach aus. Fügen Sie einige System-Java-Klassen hinzu, und wir haben viel weniger Codezeilen.

customerId = str(random.nextInt());
result = request1.POST("http://localhost:8080/transactions/add",
  "{"'"customerRewardsId"'":null,"'"customerId"'":"+ customerId + ","'"transactionDate"'":null}")
txnId = parseJsonString(result.getText(), "id")

Es werden jedoch weniger Zeilen für den Test-Setup-Code durch den Bedarf an mehr String-Wartungscode, z. B. das Analysieren von JSON-Strings, ausgeglichen. Außerdem ist die HTTPRequest -API mit geringer Funktionalität ausgestattet.

Mit The Grinder definieren wir Threads, Prozesse und Werte in einer externen Eigenschaftendatei:

grinder.threads = 100
grinder.processes = 1
grinder.runs = 10

4. Testläufe

4.1. Test Ausführung

Alle drei Tools empfehlen die Verwendung der Befehlszeile für umfangreiche Lasttests.

Gatling erfordert nur, dass JAVA HOME und GATLING HOME gesetzt sind.

Um Gatling auszuführen, verwenden wir:

GATLING__HOME\bin\gatling.bat

JMeter benötigt einen Parameter, um die GUI für den Test zu deaktivieren, wenn Sie beim Starten der GUI zur Konfiguration aufgefordert werden:

jmeter-n.cmd -t -l TestPlan.jmx -e -o[path to output folder]----

Wie bei Gatling müssen für The Grinder __JAVA__HOME__ und __GRINDERPATH__ gesetzt werden. Es braucht jedoch auch ein paar mehr Eigenschaften:

[source,powershell,gutter:,true]

set GRINDERPROPERTIES="%GRINDERPATH%\grinder.properties" set CLASSPATH="%GRINDERPATH%\lib\grinder.jar";%CLASSPATH%

Wie oben erwähnt, stellen wir eine __grinder.properties__ -Datei für zusätzliche Konfigurationen wie Threads, Läufe, Prozesse und Konsolenhosts bereit.

Zum Schluss booten wir die Konsole und die Agenten mit:

[source,powershell,gutter:,true]

java -classpath %CLASSPATH% net.grinder.Console

[source,powershell,gutter:,true]

java -classpath %CLASSPATH% net.grinder.Grinder %GRINDERPROPERTIES%

====  4.2. Testergebnisse

Jeder der Tests führte zehn Läufe mit 100 Benutzern/Threads durch. Lassen Sie uns einige Highlights auspacken:

[cols=",^,^,^,^,^",]

| ======================= | | **  Erfolgreiche Anfragen **  | **  Fehler **  | **  Gesamttestzeit (s) **  | **  Durchschnittliche Antwortzeit (ms) **  | **  Spitzendurchsatz **

| **  Gatling **  | 4100 Requests | 100 (soft) **  | 31 | 64.5 | 132 req/s

| **  JMeter **  | 4135 Anfragen | 0 | 35 | 81 | 1080 req/s

| **  The Grinder **  | 5000 Requests | 0 | 5.57 | 65.72 | 1284 req/s | ============================== ==========================================

Ein Blick zeigt, dass The Grinder 6x schneller ist als die beiden anderen Tools für den Gesamttest. Die anderen beiden taten ähnlich bei ~ 30 Sekunden. Der gleiche Schritt zwischen The Grinder und Gatling, bei dem 100 Threads erstellt wurden, dauerte 1544 ms bzw. 16 ms.

Während The Grinder mit hoher Geschwindigkeit arbeitet, kostet dies zusätzliche Entwicklungszeit und weniger Vielfalt an Ausgabedaten.

Zusätzlicher Hinweis Gatling hat 100 "weiche" Fehler aufgrund der logischen Prüfung auf eine nicht vorhandene Belohnungs-ID. Die anderen Tools zählen den if-bedingten Fehler nicht als Fehler. Diese Einschränkung ist in der Gatling-API enthalten.

[[test-summary]]

===  5. Zusammenfassung

Nun ist es an der Zeit, sich einen Überblick über alle Lasttest-Tools

[cols="^,^,^,^",]

| ======================================== | **  Gatling **  | **  JMeter **  | **  The Grinder **  | Projekt und Community | 9 | 9 | 6 | Leistung | 7 | 7 | 10 | Skriptfähigkeit/API | 7 | 9 | 8 | UI | 8 | 8 | 5 | Berichte | 9 | 7 | 6 | Integration | 7 | 9 | 7 | **  Zusammenfassung **  | **  7.8 **  | **  8.2 **  | **  7 **  | ==================== ====================

**  Gatling: **

**  Solides, poliertes Lasttest-Tool, das schöne Berichte mit ausgibt

Scala-Skripting
**  Open Source- und Enterprise-Supportstufen für das Produkt

**  JMeter: **

**  Robuste API (über GUI) für die Entwicklung von Testskripts ohne Codierung

erforderlich
**  Apache Foundation Support und hervorragende Integration mit Maven

** Der Schleifer:**

**  Schnelles Tool zum Testen der Leistung für Entwickler, die Jython verwenden

**  Serverübergreifende Skalierbarkeit bietet noch mehr Potenzial für umfangreiche Tests

Einfach ausgedrückt: Wenn Geschwindigkeit und Skalierbarkeit erforderlich sind, verwenden Sie The Grinder.

Wenn interaktiv gestaltete Grafiken dazu beitragen, einen Leistungszuwachs für eine Änderung zu zeigen, verwenden Sie Gatling.

JMeter ist das Werkzeug für komplizierte Geschäftslogik oder eine Integrationsschicht mit vielen Nachrichtentypen. Als Teil der Apache Software Foundation bietet JMeter ein ausgereiftes Produkt und eine große Community.

===  6. Schlussfolgerung

Zusammenfassend sehen wir, dass die Tools in einigen Bereichen über vergleichbare Funktionen verfügen, in anderen jedoch glänzend sind. Das richtige Werkzeug für den richtigen Job ist umgangssprachliche Weisheit, die in der Softwareentwicklung funktioniert.

Die API und Skripts finden Sie schließlich unter https://github.com/eugenp/tutorials/tree/master/testing-modules/load-testing-comparisonglich bei Github