Você escolheu a linguagem certa, pesquisou as melhores tecnologias, seu código tem uma cobertura de testes razoável e usou as melhores práticas de programação. Mas, quando o sistema finalmente foi para a produção, você recebe chamados sobre lentidão, bugs inexplicáveis são reportados e seu sistema cai antes mesmo de atingir a quantidade esperada de usuários. Seu cliente está uma fera, os usuários estão desistindo de seu aplicativo e você se pergunta onde errou.

Recentemente recebemos um projeto parecido. Um cliente nos buscou para entender por que o seu sistema caia toda vez que o fluxo de usuários aumentava. Suas funcionalidades eram utilizadas de forma sazonal e os problemas só eram descobertos em cima da hora. A solução adotada até o momento era aumentar a infraestrutura toda vez que o sistema não aguentava, só que a brincadeira ficou cara e ficou claro que não dava mais pra continuar assim.

Teste de carga é uma forma de prevenir os problemas citados. Ele tem como objetivo verificar o comportamento de sua aplicação com diferentes quantidades de usuários a utilizando. Ele pode te oferecer diversos insights sobre os pontos de melhoria, salientar os pontos de falhas e problemas que só ocorreriam quando as funcionalidades da sua aplicação fossem estressadas conjuntamente e com determinadas quantidades de usuários.

Benefícios

Quando realizamos testes de carga estamos verificando os limites de nossa aplicação. Esse conhecimento sobre nosso sistema complementa as noções que obtemos em testes de código ou testes funcionais, gerando informações como:

  • A estimativa da quantidade de carga que o hardware pode suportar antes que os limites de utilização de recursos sejam excedidos.
  • Detecção de problemas causados pela concorrência de usuários.
  • Detecção de erros em funcionalidades que só ocorrem caso o sistema seja estressado com determinadas cargas.
  • A estimativa de quantos usuários o aplicativo pode manipular antes de seu desempenho ser comprometido.
  • A identificação de pontos de melhorias de performance.
Requisitos

Para reduzir as incertezas nos resultados do teste, é importante nos atentarmos para simular da melhor forma o ambiente de produção, reproduzindo a infraestrutura e o volume de dados manuseados pela aplicação.

Precisamos criar cenários de utilização, que serão executados pelos usuários virtuais durante o teste. Eles devem ser concebidos e validados com cuidado para evitar desperdícios em cobrir cenários que não sejam representativos.

É importante que nos atentemos para o ritmo de utilização que vamos simular no nosso teste, a fim de nos aproximarmos o máximo da realidade. Ressaltando que os cenários de utilização serão  executados a nível de requisições HTTP, ou seja, o teste não manipulará os elementos do client e se comunicará diretamente com o servidor.  

É interessante que sua aplicação seja instrumentada com coletores de telemetria tais como o Application Insights , para ter uma visão detalhada sobre os pontos que apresentaram maior problema durante a utilização e mapear suas causas com mais facilidade.

Exemplo de gráficos gerados a partir da telemetria do Application Insights

Também é recomendável que você se atente aos dados coletados das máquinas dos usuários simulados, a fim de analisar como a aplicação é processada nelas.

Processo

Uma abordagem interessante para a realização do teste é aumentar gradativamente a carga de usuários até uma quantidade desejada enquanto se monitora indicadores como: tempo de resposta, a utilização de hardware, quantidade de requisições com falhas, entre outros.

Durante a simulação, os coletores fornecerão dados sobre o desempenho do sistema. Nessa abordagem, o processo do teste é dado em quatro etapas, como mostra a imagem a seguir:

Processo do teste de carga

  1. Aquecimento (warm up) : período em que o teste irá rodar sem coletar dados de indicadores de performance (utilizado para a preparação completa do ambiente de teste e do sistema sob testes).
  2. Incremento de usuários: período em que os usuários estarão sendo adicionados no teste.
  3. Período de medição com carga especificada: tempo em que a aplicação está com o número máximo de usuários estipulados no teste de carga.
  4. Cool-down: período de resfriamento do teste. Durante este período, os testes não finalizados podem continuar até serem concluídos ou até o final do período.

Nossa equipe optou pela abordagem acima para resolver o problema do nosso cliente. Ao final de cada rodada dos testes de carga, os principais pontos de melhoria eram levantados e trabalhados dentro da aplicação. Com as melhorias realizadas, o teste de carga era executado novamente, os resultados eram documentadas e o ciclo recomeçava.

Essa é uma de muitas possíveis formas de construir um teste de performance. Os testes de performance são uma atividade ampla e complexa que podem assumir várias formas, lidar com diversos riscos e fornecer uma ampla gama de valor.

Mais informações

É importante compreender os diferentes tipos de testes de desempenho, a fim de  reduzir riscos, minimizar custos e saber quando aplicar o teste apropriado. Esse artigo sobre os tipos de teste de performance pode ajudar a entender qual é o mais adequado para sua necessidade:  https://msdn.microsoft.com/en-us/library/bb924357.aspx .

Caso você tenha se interessado por testes de performance e tenha vontade de conhecer mais tipos e tangibilizar os conceitos que eu passei hoje, esse artigo da MSDN pode tirar algumas dúvidas de como fazer isso no ambiente da Microsoft: https://msdn.microsoft.com/en-us/library/dd293540(v=vs.110).aspx .

Tenho tido bastante contato com Testes de carga no ambiente Microsoft utilizando Visual Studio, VSTS e o Azure. Pretendo escrever mais conteúdos sobre o tema futuramente aqui no blog.

Mas, caso você não esteja familiarizado com o ambiente Microsoft ou gostaria de explorar outras ferramentas, existem opções como o  Apache JMeter , um software open source desenvolvido para criar e executar testes de performance.