Планирование нагрузочных тестов с помощью Apache JMeter

Завершено

В этом разделе описано, как добавить нагрузочные тесты в конвейер. Нагрузочные тесты используют Apache JMeter для имитации нескольких пользователей, которые обращаются к веб-приложению одновременно. Тесты извлекает веб-содержимое из приложения, работающего в службе приложение Azure в промежуточной среде.

Тим начинается с создания пользовательского интерфейса Apache JMeter на ноутбуке. Он запускает базовый тестовый план. Затем Тим и Мара экспортируют тестовый план в файл, который можно запустить из командной строки. Наконец, они добавляют задачи в Azure Pipelines для запуска нагрузочных тестов во время промежуточного выполнения.

Примечание.

Для краткости вам не нужно устанавливать Apache JMeter на локальном компьютере. Вы можете просто прочитать вместе.

Выполнение нагрузочных тестов из Apache JMeter

Apache JMeter — это средство нагрузочного тестирования с открытым исходным кодом, которое анализирует производительность и измеряет производительность. Отчет, который он создает, является XML-файлом.

Azure Pipelines может считывать отчет Apache JMeter и создавать граф. Для выполнения этих тестов не требуется специальное оборудование, поэтому для их запуска можно использовать агент, размещенный корпорацией Майкрософт. В сценарии Space Game вы, скорее всего, выполните эти тесты в промежуточном режиме.

Создание тестового плана

Вот как выглядит Apache JMeter на ноутбуке под управлением Linux:

Screenshot of the Apache JMeter user interface.

Вы создадите файл плана тестирования; Например, LoadTest.jmx. Затем вы добавите группу потоков в файл. Каждый имитированный пользователь выполняется в собственном потоке. Группа потоков определяет количество пользователей и количество запросов каждого пользователя.

В следующем примере показаны 10 имитированных пользователей (потоков). Каждый пользователь выполняет 10 запросов, поэтому система получает в общей сложности 100 запросов.

Screenshot of specifying the thread group in Apache JMeter.

Пример — это один запрос, сделанный JMeter. JMeter может запрашивать серверы по протоколу HTTP, FTP, TCP и нескольким другим протоколам. Примеры создают результаты, добавленные в отчет.

Затем вы добавите значения по умолчанию http-запроса и пример http-запроса в группу потоков. Имя узла веб-сайта Space Game, которое выполняется в промежуточной среде в службе приложение Azure.

Screenshot that shows specifying the HTTP request in Apache JMeter.

Предыдущий сценарий создает базовый тестовый план.

Запуск тестового плана

JMeter позволяет выполнять много видов тестов. Можно запустить тестовый план из графического пользовательского интерфейса JMeter. Однако для нагрузочных тестов документация по JMeter рекомендует запустить план тестирования из командной строки.

Вы запустите тестовый план с помощью следующей команды:

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

Аргумент -n указывает для запуска JMeter в режиме, отличном от графического интерфейса. Аргумент -t указывает файл плана тестирования, LoadTest.jmx. Аргумент -o указывает файл отчета, Results.xml.

JMeter запускает и создает файл отчета, Results.xml. В этом примере файла показаны первые несколько результатов:

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

Каждый пример создает узел в отчете. Атрибут t задает время отклика в миллисекундах (мс). Здесь вы увидите три запроса, которые заняли 180 мс, 174 мс и 160 мс.

Идеальное время запроса должно превышать одну секунду. Не более 10 процентов запросов должно занять более одной секунды. Можно настроить JMeter для отчета статистики, например минимального, максимального и среднего времени отклика или стандартного отклонения. Вы можете написать сценарий для предоставления этих сведений.

Чтобы визуализировать результаты теста, необходимо предоставить их в формате, который понимает Azure Pipelines. Azure Pipelines может анализировать XML-файл, содержащий результаты теста, но файл должен находиться в поддерживаемом формате. Поддерживаемые форматы включают CTest, JUnit (включая PHPUnit), NUnit 2, NUnit 3, Visual Studio Test (TRX) и xUnit 2. Можно написать XSLT-файл, который преобразует результаты JMeter в JUnit.

Преобразование отчета в JUnit

XSLT означает преобразования XSL или преобразования языка таблицы стилей eXtensible. XSLT-файл похож на XML-файл, но позволяет преобразовать XML-документ в другой формат XML.

Помните наши требования к нагрузочных тестов:

  • Среднее время запроса должно быть меньше одного секунды.
  • Не более 10 процентов запросов должно занять более одной секунды.

Вот как выглядит XSLT-файл, соответствующий этим требованиям:

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

Мы не будем углубляться в то, как работает XSL здесь. Но чтобы свести к выводу, этот файл сначала собирает следующие данные из выходных данных JMeter:

  • Каждое время HTTP-запроса.

    Он собирает эти данные, выбрав t атрибут из каждого httpSample элемента. (./httpSample/@t)

  • Каждое сообщение об ошибке.

    Он собирает эти данные, выбрав все failureMessage узлы из документа. (./httpSample/assertionResult/failureMessage)

XSLT-файл также задает пороговое значение 1000 мс. Это время отклика — это максимальное значение, которое мы определили ранее.

Учитывая эти переменные, XSLT-файл предоставляет общее количество тестов и общее количество сбоев. Затем он предоставляет следующие два тестовых варианта:

  • Среднее время отклика и сбой, если среднее значение превышает пороговое значение 1000 мс.
  • Максимальное время отклика и сбой, если более 10 процентов запросов превышают пороговое значение 1000 мс.

Результаты XSLT соответствуют формату JUnit, который понимает Azure Pipelines. Вы можете назвать XSLT-файл JMeter2JUnit.xsl.

Далее потребуется процессор XSLT. В этом примере мы будем использовать xsltproc, которое является средством командной строки для применения таблиц стилей XSLT к XML-документам.

Можно установить xsltproc следующим образом:

sudo apt-get install xsltproc

Затем необходимо запустить xsltproc для преобразования отчета JMeter в JUnit:

xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml

Ниже приведен полученный файл JUnit, 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>

В этом примере среднее время отклика составляет 170 мс. Максимальное время отклика — 373 мс. Ни тестовый случай не создает сбой, так как оба раза ниже порогового значения 1000 мс.

Вскоре эти тесты будут выполняться в конвейере. Вы можете подумать о Results.xml, файл, который JMeter записывает, в качестве промежуточного файла, который не опубликован в результатах теста конвейера. JUnit.xml является окончательным файлом отчета. Этот файл публикуется в конвейере, чтобы команда могли визуализировать результаты.