Planera belastningstester med hjälp av Apache JMeter

Slutförd

I det här avsnittet utforskar du belastningstestning och lär dig hur du lägger till belastningstester i pipelinen. Belastningstesterna använder Apache JMeter för att simulera flera användare som har åtkomst till webbappen samtidigt. Testerna hämtar webbinnehållet från appen som körs på Azure App Service i mellanlagringsmiljön.

Tim börjar med att ta upp Apache JMeter-användargränssnittet på en bärbar dator. Han kör en grundläggande testplan. Sedan exporterar Tim och Mara testplanen till en fil som kan köras från kommandoraden. Slutligen lägger de till uppgifter i Azure Pipelines för att köra belastningstesterna under mellanlagringen.

Kommentar

För korthet behöver du inte installera Apache JMeter på din lokala dator. Du kan bara läsa med.

Köra belastningstester från Apache JMeter

Apache JMeter är ett verktyg för belastningstestning med öppen källkod som analyserar och mäter prestanda. Rapporten den genererar är en XML-fil.

Azure Pipelines kan läsa Apache JMeter-rapporten och generera ett diagram. Du behöver ingen särskild maskinvara för att köra dessa tester, så du kan använda en Microsoft-värdbaserad agent för att köra dem. I scenariot Space Game skulle du förmodligen köra dessa tester i Mellanlagring.

Skapa testplanen

Så här ser Apache JMeter ut på en bärbar dator som kör Linux:

Screenshot of the Apache JMeter user interface.

Du skulle skapa en ny testplansfil. till exempel LoadTest.jmx. Sedan lägger du till en trådgrupp i filen. Varje simulerad användare körs på sin egen tråd. En trådgrupp styr antalet användare och antalet varje användares begäranden.

I följande exempel visas 10 simulerade användare (trådar). Varje användare gör 10 begäranden, så systemet får totalt 100 begäranden.

Screenshot of specifying the thread group in Apache JMeter.

En sampler är en enda begäran som görs av JMeter. JMeter kan köra frågor mot servrar via HTTP, FTP, TCP och flera andra protokoll. Exempel genererar de resultat som läggs till i rapporten.

Därefter lägger du till Http Request Defaults och en Http Request sampler i trådgruppen. Du anger värdnamnet för webbplatsen Space Game som körs i mellanlagringsmiljön i Azure App Service.

Screenshot that shows specifying the HTTP request in Apache JMeter.

I föregående scenario skapas en grundläggande testplan.

Kör testplanen

Med JMeter kan du köra många typer av tester. Det går att köra testplanen från det grafiska användargränssnittet för JMeter. För belastningstester rekommenderar JMeter-dokumentationen dock att du kör testplanen från kommandoraden.

Du skulle köra testplanen med hjälp av det här kommandot:

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

Argumentet -n anger att JMeter ska köras i icke-GUI-läge. Argumentet -t anger testplansfilen LoadTest.jmx. Argumentet -o anger rapportfilen Results.xml.

JMeter kör och producerar rapportfilen Results.xml. Det här exemplet på filen visar de första resultaten:

<?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>

Varje exempel genererar en nod i rapporten. Attributet t anger svarstiden i millisekunder (ms). Här visas tre begäranden som tog 180 ms, 174 ms och 160 ms.

De ideala begärandetiderna bör i genomsnitt vara mindre än en sekund. Högst 10 procent av begärandena bör ta mer än en sekund. Du kan konfigurera JMeter för att rapportera statistik, till exempel minsta, högsta och genomsnittliga svarstider eller standardavvikelsen. Du kan skriva ett skript för att tillhandahålla den här informationen.

För att visualisera testresultaten måste du ange dem i ett format som Azure Pipelines förstår. Azure Pipelines kan parsa en XML-fil som innehåller testresultat, men filen måste vara i ett format som stöds. Format som stöds är CTest, JUnit (inklusive PHPUnit), NUnit 2, NUnit 3, Visual Studio Test (TRX) och xUnit 2. Du kan skriva en XSLT-fil som konverterar JMeter-resultaten till JUnit.

Transformera rapporten till JUnit

XSLT står för XSL-transformeringar eller eXtensible Stylesheet Language Transformations. En XSLT-fil liknar en XML-fil, men du kan omvandla ett XML-dokument till ett annat XML-format.

Kom ihåg våra krav för belastningstester:

  • Den genomsnittliga begärandetiden bör vara mindre än en sekund.
  • Högst 10 procent av begärandena bör ta mer än en sekund.

Så här ser en XSLT-fil som uppfyller dessa krav ut:

<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>

Vi går inte in på hur XSL fungerar här. Men för att sammanfatta samlar den här filen först in följande data från JMeter-utdata:

  • Varje HTTP-begärandetid.

    Den samlar in dessa data genom att t välja attributet från varje httpSample element. (./httpSample/@t)

  • Varje felmeddelande.

    Den samlar in dessa data genom att välja alla failureMessage noder i dokumentet. (./httpSample/assertionResult/failureMessage)

XSLT-filen anger också tröskelvärdet till 1 000 ms. Den här svarstiden är det högsta som vi definierade tidigare.

Med tanke på dessa variabler innehåller XSLT-filen det totala antalet tester och det totala antalet fel. Den tillhandahåller sedan följande två testfall:

  • Genomsnittlig svarstid och ett fel om genomsnittet överskrider tröskelvärdet på 1 000 ms.
  • Den maximala svarstiden och ett fel om mer än 10 procent av begäranden överskrider tröskelvärdet på 1 000 ms.

Resultatet av XSLT matchar JUnit-formatet, vilket Azure Pipelines förstår. Du kan ge XSLT-filen namnet JMeter2JUnit.xsl.

Därefter behöver du en XSLT-processor. I det här exemplet använder vi xsltproc, som är ett kommandoradsverktyg för att tillämpa XSLT-formatmallar på XML-dokument.

Du kan installera xsltproc på följande sätt:

sudo apt-get install xsltproc

Därefter skulle du köra xsltproc för att omvandla JMeter-rapporten till JUnit:

xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml

Här är den resulterande JUnit-filen 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>

I det här exemplet är den genomsnittliga svarstiden 170 ms. Den maximala svarstiden är 373 ms. Inget av testfallen genererar ett fel eftersom båda gångerna ligger under tröskelvärdet på 1 000 ms.

Snart ska du köra de här testerna i pipelinen. Du kan tänka på Results.xml, filen som JMeter skriver, som en mellanliggande fil som inte publiceras till pipelinens testresultat. JUnit.xml är den slutliga rapportfilen. Den här filen publiceras i pipelinen så att teamet kan visualisera resultaten.