Planejar testes de carga usando o Apache JMeter
Nesta seção, você explorará o teste de carga e aprenderá a adicionar testes de carga ao pipeline. Os testes de carga usam o Apache JMeter para simular vários usuários que acessam o aplicativo Web simultaneamente. Os testes buscam o conteúdo da Web do aplicativo que é executado no Serviço de Aplicativo do Azure no ambiente de Preparo.
Pedro começa colocando a interface do usuário do Apache JMeter em um laptop. Ele executa um plano de teste básico. Em seguida, Pedro e Clara exportam o plano de teste para um arquivo que pode ser executado na linha de comando. Por fim, eles adicionam tarefas ao Azure Pipelines para executar os testes de carga durante o Preparo.
Observação
Para resumir, você não precisa instalar o Apache JMeter no computador local. Você pode apenas ler.
Executar testes de carga do Apache JMeter
O Apache JMeter é uma ferramenta de teste de carga de código aberto que analisa e mede o desempenho. O relatório gerado por ela é um arquivo XML.
O Azure Pipelines pode ler o relatório do Apache JMeter e gerar um grafo. Você não precisa de nenhum hardware especial para executar esses testes, portanto, você poderá usar um agente hospedado pela Microsoft para executá-los. No cenário do Space Game, você provavelmente executaria esses testes no Processo de preparo.
Criar o plano de teste
Veja a aparência do Apache JMeter em um laptop que executa o Linux:
Você criaria um novo arquivo de plano de teste; por exemplo, LoadTest.jmx. Em seguida, você adicionaria um Grupo de Threads ao arquivo. Cada usuário simulado é executado no próprio thread. Um grupo de threads controla o número de usuários e o número de solicitações de cada usuário.
O exemplo a seguir mostra 10 usuários simulados (threads). Cada usuário faz 10 solicitações, portanto, o sistema obtém um total de 100 solicitações.
Uma amostra é uma só solicitação feita pelo JMeter. O JMeter pode consultar servidores por HTTP, FTP, TCP e vários outros protocolos. Os exemplos geram os resultados que são adicionados ao relatório.
Em seguida, você adicionaria Padrões de solicitação HTTP e uma amostra de Solicitação HTTP ao grupo de threads. Você forneceria o nome do host do site do Space Game que é executado no ambiente de preparo no Serviço de Aplicativo do Azure.
O cenário anterior cria um plano de teste básico.
Executar o plano de teste
O JMeter permite que você execute muitos tipos de testes. É possível executar seu plano de teste na interface gráfica do usuário do JMeter. Para testes de carga, no entanto, a documentação do JMeter recomenda que você execute o plano de teste na linha de comando.
Você executaria o plano de teste usando este comando:
apache-jmeter-5.4.1/bin/./jmeter -n -t LoadTest.jmx -o Results.xml
O argumento -n
especifica a execução do JMeter no modo não GUI. O argumento -t
especifica o arquivo de plano de teste, LoadTest.jmx. O argumento -o
especifica o arquivo de relatório, Results.xml.
O JMeter executa e produz o arquivo de relatório, Results.xml. Este exemplo do arquivo mostra os primeiros resultados:
<?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>
Cada exemplo produz um nó no relatório. O atributo t
especifica o tempo de resposta em ms (milissegundos). Aqui, você verá três solicitações que levaram 180 ms, 174 ms e 160 ms.
Os tempos de solicitação ideais devem ter uma média inferior a um segundo. Não mais de 10% das solicitações devem levar mais de um segundo. Você pode configurar o JMeter para relatar estatísticas, como os tempos de resposta mínimo, máximo e médio ou o desvio padrão. Você pode escrever um script para ajudar a fornecer essas informações.
Para visualizar os resultados do teste, você precisa fornecê-los em um formato que o Azure Pipelines entenda. O Azure Pipelines pode analisar um arquivo XML que contém os resultados de teste, mas o arquivo precisa estar em um formato com suporte. Os formatos com suporte incluem CTest, JUnit (incluindo PHPUnit), NUnit 2, NUnit 3, Visual Studio Test (TRX) e xUnit 2. Você pode escrever um arquivo XSLT que converte os resultados do JMeter em JUnit.
Transformar o relatório em JUnit
XSLT significa transformações XSL ou transformações de linguagem de folha de estilo extensível. Um arquivo XSLT é semelhante a um arquivo XML, mas permite transformar um documento XML em outro formato XML.
Lembre-se de nossos requisitos para testes de carga:
- O tempo médio de solicitação deve ser inferior a um segundo.
- Não mais de 10% das solicitações devem levar mais de um segundo.
Veja como é um arquivo XSLT que atende a esses requisitos:
<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>
Não vamos nos aprofundar em como o XSL funciona aqui. Porém, para resumir, esse arquivo primeiro coleta os seguintes dados da saída JMeter:
O tempo de cada solicitação HTTP.
Ele coleta esses dados selecionando o atributo
t
de cada elementohttpSample
. (./httpSample/@t
)Cada mensagem de falha.
Ele coleta esses dados selecionando todos os nós
failureMessage
do documento. (./httpSample/assertionResult/failureMessage
)
O arquivo XSLT também define o valor do limite como 1.000 ms. Esse tempo de resposta é o máximo que definimos anteriormente.
Dadas essas variáveis, o arquivo XSLT fornece o número total de testes e o número total de falhas. Em seguida, ele fornece estes dois casos de teste:
- O tempo médio de resposta e uma falha se a média exceder o limite de 1.000 ms.
- O tempo máximo de resposta e uma falha se mais de 10% das solicitações excederem o limite de 1.000 ms.
Os resultados do XSLT correspondem ao formato JUnit, que o Azure Pipelines compreende. Você pode nomear seu arquivo XSLT JMeter2JUnit.xsl.
Em seguida, você precisaria de um processador XSLT. Neste exemplo, usaremos xsltproc, que é uma ferramenta de linha de comando para aplicar folhas de estilo XSLT a documentos XML.
Você poderia instalar xsltproc da seguinte maneira:
sudo apt-get install xsltproc
Em seguida, você executaria xsltproc para transformar o relatório JMeter em JUnit:
xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml
Aqui está o arquivo JUnit resultante, 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>
Neste exemplo, o tempo médio de resposta é de 170 ms. O tempo máximo de resposta é de 373 ms. Nenhum caso de teste gera uma falha, porque ambos os tempos estão abaixo do limite de 1.000 ms.
Em breve, você executará esses testes no pipeline. Você pode pensar em Results.xml, o arquivo que o JMeter grava, como um arquivo intermediário que não é publicado nos resultados de teste do pipeline. JUnit.xml é o arquivo de relatório final. Esse arquivo é publicado no pipeline para que a equipe possa visualizar os resultados.