Planen von Auslastungstests mithilfe von Apache JMeter

Abgeschlossen

In diesem Abschnitt erkunden Sie Auslastungstests und erfahren, wie Sie der Pipeline Auslastungstests hinzufügen. Für die Auslastungstests wird Apache JMeter verwendet, um mehrere Benutzer zu simulieren, die gleichzeitig auf die Web-App zugreifen. Die Tests rufen den Webinhalt von der App ab, die in Azure App Service in der Stagingumgebung ausgeführt wird.

Tim richtet zunächst die Apache JMeter-Benutzeroberfläche auf einem Laptop ein. Er führt einen einfachen Testplan aus. Anschließend exportieren Tim und Mara den Testplan in eine Datei, die über die Befehlszeile ausgeführt werden kann. Schließlich fügen Sie Azure Pipelines Tasks hinzu, um die Auslastungstests während der Stagingphase auszuführen.

Hinweis

Sie müssen Apache JMeter zu diesem Zeitpunkt nicht auf Ihrem lokalen Computer installieren. Sie können es einfach mitlesen.

Ausführen von Auslastungstests über Apache JMeter

Apache JMeter ist ein Open-Source-Tool für Auslastungstests, das die Leistung analysiert und misst. Es generiert einen Bericht in Form einer XML-Datei.

Azure Pipelines kann den Apache JMeter-Bericht lesen und ein Diagramm generieren. Sie benötigen keine spezielle Hardware zum Ausführen dieser Tests, daher können Sie einen von Microsoft gehosteten Agent verwenden. Im Szenario „Space Game“ führen Sie diese Tests wahrscheinlich im Stagingprozess aus.

Erstellen des Testplans

So sieht Apache JMeter auf einem Laptop unter Linux aus:

Screenshot of the Apache JMeter user interface.

Sie erstellen eine neue Testplandatei, zum Beispiel LoadTest.jmx. Anschließend fügen Sie der Datei eine Threadgruppe hinzu. Jeder simulierte Benutzer wird in einem eigenen Thread ausgeführt. Eine Threadgruppe steuert die Anzahl der Benutzer und der Benutzeranforderungen.

Das folgende Beispiel zeigt zehn simulierte Benutzer (Threads). Jede*r Benutzer*in sendet 10 Anforderungen, sodass das System insgesamt 100 Anforderungen erhält.

Screenshot of specifying the thread group in Apache JMeter.

Ein Sampler ist eine einzelne Anforderung von JMeter. JMeter kann Server über HTTP, FTP, TCP und verschiedene andere Protokolle abfragen. Samplers generieren die Ergebnisse, die dem Bericht hinzugefügt werden.

Als Nächstes fügen Sie der Threadgruppe Standardwerte für HTTP-Anforderungen und einen Sampler für HTTP-Anforderungen hinzu. Sie geben den Hostnamen der Website von Space Game an, die in der Stagingumgebung von Azure App Service ausgeführt wird.

Screenshot that shows specifying the HTTP request in Apache JMeter.

Im vorherigen Szenario wird ein grundlegender Testplan erstellt.

Ausführen des Testplans

Mit JMeter kann man viele verschiedene Tests ausführen. Du kannst den Testplan über die grafische Benutzeroberfläche von JMeter auszuführen. Für Auslastungstests empfiehlt die JMeter-Dokumentation jedoch, den Testplan über die Befehlszeile auszuführen.

Sie führen den Testplan mit diesem Befehl aus:

apache-jmeter-5.4.1/bin/./jmeter -n -t LoadTest.jmx -o Results.xml

Das Argument -n gibt an, dass JMeter nicht im GUI-Modus ausgeführt werden soll. Das Argument -t gibt die Testplandatei LoadTest.jmx an. Das Argument -o gibt die Berichtsdatei Results.xml an.

JMeter wird ausgeführt und generiert die Berichtsdatei Results.xml. In diesem Beispiel für die Datei werden die ersten Ergebnisse angezeigt:

<?xml version="1.0" encoding="UTF-8"?>
<testResults version="1.2">
<httpSample t="180" it="0" lt="95" ct="35" ts="1569306009772" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40871" sby="144" ng="1" na="1">
  <java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>
<httpSample t="174" it="0" lt="96" ct="38" ts="1569306009955" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40869" sby="144" ng="1" na="1">
  <java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>
<httpSample t="160" it="0" lt="121" ct="35" ts="1569306010131" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40879" sby="144" ng="2" na="2">
  <java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>

Jedes Beispiel erstellt einen Knoten im Bericht. Das Attribut t gibt die Antwortzeit in Millisekunden (ms) an. Hier sehen Sie drei Anforderungen, die 180 ms, 174 ms und 160 ms gedauert haben.

Die idealen Anforderungszeiten sollten unter einer Sekunde liegen. Maximal 10 Prozent der Anforderungen sollten mehr als eine Sekunde dauern. Du kannst JMeter so konfigurieren, dass Statistiken wie minimale, maximale und durchschnittliche Antwortzeiten oder die Standardabweichung im Bericht erfasst werden. Sie könnten ein Skript zum Bereitstellen dieser Informationen schreiben.

Zum Visualisieren der Testergebnisse müssen Sie sie in einem Format bereitstellen, das mit Azure Pipelines kompatibel ist. Azure Pipelines kann eine XML-Datei analysieren, die Testergebnisse enthält, aber die Datei muss in einem unterstützten Format vorliegen. Zu den unterstützten Formaten gehören CTest, JUnit – einschließlich PHPUnit –, NUnit 2, NUnit 3, Visual Studio Test (TRX) und xUnit 2. Sie könnten eine XSLT-Datei schreiben, die die JMeter-Ergebnisse in JUnit konvertiert.

Transformieren des Berichts in JUnit

XSLT steht für XSL Transformations oder Extensible Stylesheet Language Transformations. Eine XSLT-Datei ähnelt einer XML-Datei, ermöglicht jedoch das Transformieren eines XML-Dokuments in ein anderes XML-Format.

Erinnern Sie sich an unsere Anforderungen für Auslastungstests:

  • Die durchschnittliche Anforderungsdauer sollte weniger als eine Sekunde betragen.
  • Maximal 10 Prozent der Anforderungen sollten mehr als eine Sekunde dauern.

So sieht eine XSLT-Datei aus, die diese Anforderungen erfüllt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
  <xsl:template match="/testResults">
    <xsl:variable name="times" select="./httpSample/@t" />
    <xsl:variable name="failures" select="./httpSample/assertionResult/failureMessage" />
    <xsl:variable name="threshold" select="1000" />
    <testsuite>
      <xsl:attribute name="tests"><xsl:value-of select="count($times)" /></xsl:attribute>
      <xsl:attribute name="failures"><xsl:value-of select="count($failures)" /></xsl:attribute> 
      <testcase>
          <xsl:variable name="avg-time" select="sum($times) div count($times)" />
          <xsl:attribute name="name">Average Response Time</xsl:attribute>
          <xsl:attribute name="time"><xsl:value-of select="format-number($avg-time div 1000,'#.##')"/></xsl:attribute>
          <xsl:if test="$avg-time > $threshold">
            <failure>Average response time of <xsl:value-of select="format-number($avg-time,'#.##')"/> exceeds <xsl:value-of select="$threshold"/> ms threshold.</failure>
          </xsl:if> 
      </testcase>
      <testcase>
          <xsl:variable name="exceeds-threshold" select="count($times[. > $threshold])" />
          <xsl:attribute name="name">Max Response Time</xsl:attribute>
          <xsl:attribute name="time"><xsl:value-of select="math:max($times) div 1000"/></xsl:attribute>
          <xsl:if test="$exceeds-threshold > count($times) * 0.1">
            <failure><xsl:value-of select="format-number($exceeds-threshold div count($times) * 100,'#.##')"/>% of requests exceed <xsl:value-of select="$threshold"/> ms threshold.</failure>
          </xsl:if>
      </testcase>
    </testsuite>
  </xsl:template>
</xsl:stylesheet>

Die Funktionsweise von XSL wird hier nicht erläutert. Zusammengefasst erfasst diese Datei die folgenden Daten aus der JMeter-Ausgabe:

  • Die einzelnen HTTP-Anforderungsdauern:

    Diese Daten werden erfasst, indem das Attribut t jedes httpSample-Elements ausgewählt wird. (./httpSample/@t)

  • Alle Fehlermeldungen:

    Diese Daten werden erfasst, indem alle failureMessage-Knoten des Dokuments ausgewählt werden. (./httpSample/assertionResult/failureMessage)

Die XSLT-Datei legt zudem den Schwellenwert auf 1.000 ms fest. Diese Antwortzeit ist das Maximum, das wir zuvor definiert haben.

Anhand dieser Variablen gibt die XSLT-Datei die Gesamtanzahl der Tests und Fehler an. Dann sind diese beiden Testfälle möglich:

  • Die durchschnittliche Antwortzeit und ein Fehler, wenn diese den Schwellenwert von 1.000 ms überschreitet
  • Die maximale Antwortzeit und ein Fehler, wenn mehr als 10 Prozent der Anforderungen den Schwellenwert von 1.000 ms überschreiten

Die Ergebnisse der XSLT-Datei entsprechen dem JUnit-Format, das mit Azure Pipelines kompatibel ist. Sie könnten ihre XSLT-Datei JMeter2JUnit.xsl nennen.

Als Nächstes benötigen Sie einen XSLT-Prozessor. In diesem Beispiel verwenden wir xsltproc, ein Befehlszeilentool zum Anwenden von XSLT-Stylesheets auf XML-Dokumente.

Sie könnten xsltproc wie folgt installieren:

sudo apt-get install xsltproc

Als Nächstes führen Sie xsltproc aus, um den JMeter-Bericht in JUnit zu transformieren:

xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml

Hier sehen Sie die resultierende JUnit-Datei, JUnit.xml:

<?xml version="1.0" encoding="UTF-8"?>
<testsuite xmlns:math="http://exslt.org/math" tests="100" failures="0">
  <testcase name="Average Response Time" time="0.17"/>
  <testcase name="Max Response Time" time="0.373"/>
</testsuite>

In diesem Beispiel beträgt die durchschnittliche Antwortzeit 170 ms. Die maximale Antwortzeit beträgt 373 ms. Keiner der Testfälle generiert einen Fehler, da beide Zeiten unter den Schwellenwert von 1.000 ms liegen.

In Kürze führen Sie diese Tests in der Pipeline aus. Stellen Sie sich Results.xml (die von JMeter geschriebene Datei) als temporäre Datei vor, die nicht in den Testergebnissen der Pipeline veröffentlicht wird. JUnit.xml ist die finale Berichtsdatei. Diese Datei wird in der Pipeline veröffentlicht, damit das Team die Ergebnisse visualisieren kann.