Testes de Performance: O que são e como utilizamos.

Testes de Performance: O que são e como utilizamos.

Testar ou não testar

Testar ou não testar... Isso já não é uma opção no cotidiano dos desenvolvedores. Hoje em dia o desenvolvimento de software em geral atingiu níveis de maturidade onde testar é tão importante quanto desenvolver

Nós, enquanto desenvolvedores, na maioria das vezes nos atemos aos testes unitários a nível de “services” ou aos testes da “controler”: basicamente o que podemos rodar a nível de Kernel mesmo que estejamos falando de testes E2E. Porém, existem diversos outros testes, não tão fomentados assim, para se explorar(conforme necessidade). Nesse artigo irei abordar um deles: o teste da família "Performance". Denomino dessa maneira no decorrer do texto, mesmo sendo a intitulação “Carga” e “Estresse” também bem comuns para o mesmo tipo de teste.

O que são os testes de Performance ?

Quando falamos dos tipos de testes, é comum utilizarmos a famosa pirâmide de teste, que é usada para ilustrar a relação entre “quantidade de testes” por tipo/camada que deveria ser empregada, qualitativamente falando e sua correlação com à velocidade de execução e o custo de manutenção que tende a aumentar quanto mais “distante do código" se vai. A pirâmide de Mike Cohn normalmente vem segmentada em 3 sessões: Teste Unitários, Testes de Integração e Componentes e Testes End to End. Nosso amigo, o Teste de Performance, vem inserido nesse último.

O que os testes de Performance buscam garantir ?

miranha


Os testes de Performance ajudam a responder a tradicional pergunta "Minha aplicação funciona?" mas principalmente consegue responder outra tão importante o quanto, a "Como minha aplicação se comporta?".

Características do teste de Performance:

  • Entender o comportamento de uma aplicação durante seu funcionamento;
  • Normalmente visa atingir um número de requisições, em determinado intervalo com condições desejadas;
  • Utiliza algum tipo de ferramenta de mercado para atingir esse objetivo (o que não é obrigatório, pois o paradigma do teste não necessariamente exige uma).

Porquê e quando utilizar o teste de Performance

Voltando à ideia da pirâmide de testes, os testes de Performance são E2E,  logo sua manutenção é alta e sua execução e configuração são custosas. A primeira pergunta que devemos fazer é: meu cenário precisa de um teste de Performance?

Testes de Performance normalmente são aplicados para prever o comportamento do seu serviço em condições de consumo e estresse específicas, como por exemplo o lançamento de um sistema que, em teoria terá grande número de acessos, uma vez que pontos como estabilidade, tempo de resposta, escalabilidade e outros variam em um cenário real, com altos níveis de consumo. Portanto, esse seria um dos casos onde utilizar um teste de Performance salvaria vidas.

Alguns outros cenários comuns para o testes de Performance seriam:

  • Testar se o ambiente está preparado para um grande aumento de acesso, como um e-commerce antes da black-friday;
  • Validar se seus serviços auto-scale estão funcionando como esperado;
  • Garantir que as integrações que sua aplicação faz não se tornem pontos de gargalo;
  • Mensurar o consumo de dependências, como recursos de hardware, ou a latência da rede;
  • Estabelecer métricas críticas para os serviços, para disparo de alertas e monitoração.

... entre outros problemas que só seriam encontrados no ambiente de produção.

Aqui no Furacão

furacao

Aqui na Vórtx, por exemplo, utilizamos os testes de Performance para simular o grande aumento de consumo que algumas de nossas aplicações relacionadas ao informe de rendimentos, recebem nos primeiros meses do ano por conta da declaração do imposto de renda.

Outro caso onde esse tipo de teste foi de grande valia, foi na troca do nosso gateway. Ocasião em que precisávamos garantir que não haveria queda na Performance geral, simulando um cenário igual ao nosso dia-a-dia no ambiente produtivo.

Diferenciando a Família (Load Test / Performance Test / Stress Test)

Os testes de “Performance” podem ser divididos em três tipos principais: Testes de Carga, Performance e Estresse. Abaixo, será abordado sobre cada tipo e subtipo.

Load Test (Teste de Carga)

É o teste comumente executado nas fases iniciais de um projeto, em um ambiente controlado, normalmente algo como pré-produção. Visa atingir a quantidade e condições de acesso. Essas condições costumam ser um benchmark calculado em conjunto ao time de negócios. A ideia é fazer um pré-teste, baseado na quantidade de requisições que a aplicação vai receber em seu “lançamento”.

Stress Test (Teste de Estresse)

Um pouco diferente do teste de carga, o Stress Test visa atingir o LIMITE do sistema (A meta é quebrar o “brinquedo”).

Também executado nas etapas iniciais de um novo projeto ou antecedendo momentos de grande consumo do sistema, como por exemplo uma black-friday para um sistema de e-commerce.

Normalmente os números a serem atingidos são da ordem de 5 a 10 vezes o benchmark, ou estipulados pelo time de tecnologia , para identificar o que "cai" primeiro.

Tendo em mente que os testes de "Performance" são testes E2E, a ideia aqui é saber de forma geral o quanto sua aplicação suporta. Queremos encontrar os números limites que são extremamente úteis para se ter em mãos em momentos de instabilidades, ou para prever uma necessidade de escalabilidade.

Esse teste também é super interessante para prever possíveis "gargalos" na sua aplicação em algum ponto de integração. Imagine um cenário onde o teste unitário e os de integração foram um sucesso e você alcançou o desempenho previsto no seu teste de carga, porém quando sua aplicação é exposta à uma carga 10% maior, ela acaba caindo, algo que você acreditava ser tranquilo para seu serviço estando todo em auto-scale.

Você então descobre que a culpa é do micro-serviço terceiro que é consumido só para consultar CPF em um quinto das requisições, mas ele não aguentou o prometido pelo fornecedor. Ou ainda pode gerar insumos como a descoberta de que as PROCs do seu banco não estão tão bem otimizadas e talvez você precise de uma camada de cash para aguentar um aumento de demanda.

Performance Test (Teste de Performance)

O Teste de Performance nada mais é que a combinação dos seus irmãos (um pouquinho de cada um), mas no geral, é como se TUDO fosse teste de Performance.  Mas como assim?

Teste de Performance visa saber o “limite saudável" da sua aplicação. Seria algo acima do seu bench-mark (Load Test) e algo abaixo do momento de desastre (Stress Test). Logo é a faixa máxima da sua aplicação com taxas definidas como aceitáveis por quem está o aplicando, por exemplo:

  • 1% de chamadas com erro;
  • 40% de aumento no tempo de resposta;
  • consumo de X reais no seu serviço com auto-scale;
  • 2 em 50 emails enviados perdidos.

Esse tipo de métrica não vai ser o cenário ideal, mas é aceitável no caso do consumo da sua aplicação crescer. É muito valioso saber o quão bem seu sistema lida com uma taxa ponderada de erros.

Normalmente ele é executado no ambiente produtivo, a partir das métricas capturadas pelo teste de Carga e Estresse previamente.

Ele também vai ser executado sempre em uma boa esteira de desenvolvimento, não só na criação da feature, sendo que as métricas capturadas e aferidas deveriam tentar ser alcançadas em todo deploy relevante, para verificar  se alguma alteração pode ter causado uma mudança ou impacto maior. É importante ressaltar que não é necessário  testar todo o seu sistema, somente a parte que interessa para aquela feature.

Outras sub-categorias de testes de Performance

Endurance Teste (teste de duração): Um teste no qual você deixa seu produto rodando e sendo consumido por muito tempo. Mas, qual o sentido ?

Saber problemas que podem aparecer em runtime de longo prazo, por exemplo:

  • Como esse software vai gerenciar memória, o heap e o gerenciamento de thread;
  • Como sua aplicação aloca logs dentro da "máquina" e se suas regras de compressão de descarte estão funcionando;
  • Como o gerenciamento de certificados do container/máquina conforme o suas definições de segurança, entre outros.

Peak/Spike test (Teste de Pico): Testar o pico máximo que a aplicação sabe gerenciar, descobrir o quão rápido sua aplicação vai escalar para atender essa demanda, ou até se planejar para "escalar o sistema, antes da demanda".

Exemplo: Você possui uma aplicação que tem altos picos de volume na hora do almoço, como por exemplo jogos mobiles. Escalar sua aplicação apenas durante este horário, já estudado pela sua área de negócio, reduz custos da sua operação.

O outro valor gerado deste teste é  saber em quanto tempo e como sua aplicação se recupera de um “desastre".

Volume Test (Teste de Volume): É o teste de "Performance" focado na transação de dados. Estressar sua aplicação em relação às quantidades de dados a serem processadas, salvas e ingeridas é útil para verificar se o banco de dados foi bem construído e dimensionado. Serve também para estruturas de data lake, ambientes hadoop e afins.

Ferramentas que podemos Utilizar


Se falarmos apenas de gerar muitas requisições, é possível fazer isso de diversas formas. Porém, quando falamos em coletar métricas precisas, controlar variáveis, aplicar lógicas e ainda consumir uma visão analítica, já existem soluções disponíveis no mercado hoje que nos auxiliam nos testes de Performance .

O intuito deste artigo não é desenvolver um teste de Performance e sim explicar sobre estes. Mesmo assim, vou me utilizar de alguns recursos do JMeter para compartilhar minha experiência no assunto;

JMeter

A definição da Apache para o JMeter é

" The Apache JMeter™ application is open-source software, a 100% pure Java application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions."​ (apache.com)

É uma ferramenta gratuita, cheia de recursos e que performa muito bem, tanto na UI quanto via CMD.

Esse é um projeto Jmeter construído por mim para uma apresentação, vou utilizar ele aqui para listar alguns dos principais recursos, como:

  • Definição de variáveis de ambiente;
  • importação de valores de arquivos .csv;
  • Controladores de RPS/TPS;
  • Implementação de chamadas HTTP e todos seus recursos;
  • Controladores lógicos em diversas linguagens (shell, groove, js);
  • Extratores de retornos de chamadas;
  • Ferramentas de “asserts”;
  • Tabela de resultados sumarizados e gráfico de resultados;
  • Visão detalhada da execução individual de cada requisição;
  • Logs e extração de todo tipo de informação de resultado;

Gatling

Gatling é uma outra ferramenta de teste de Performance bem popular. Possui uma versão grátis e uma enterprise, e gera um relatório visualmente rico em minha opinião. Gatling, ironicamente, não possui uma interface visual para desenvolvimento. Dessa forma você precisa construir um código Scala para criar seus testes. Para mais informações, consulte a página.

Estes são só alguns recursos que utilizei, tendo muitos outros para cada tipo de necessidade. Você pode ter acesso a um conteúdo de hands-on mais detalhado, acessando o minha apresentação no YouTube.

Problema comum

Agora que já falamos das ferramentas de mercado, acho que vale a pena compartilhar com vocês alguns “macetes” que podem ajudar nos problemas comumente enfrentados ao começar os testes de Performance .

A limitação do requisitante

Um problema comum quando se executa testes de carga é querer atingir limites altos demais para o seu PC, enviesando seus testes, sejam por não conseguir atingir um benchmark ou por não conseguir derrubar o sistema alvo. E existem algumas forma simples de driblar isso:

Dividir para conquistar :

Diminuir o seu “alvo” de forma proporcional é efetivo. Por exemplo, digamos que você possui 4 containers de uma aplicação, atrás de um load balancer, e você deseja atingir 400 tps. Então, se você atingir 100 tps em 1 container, você vai estar gerando o mesmo nível de estresse. É uma regra de três básica.

Chame um amigo

A lógica contrária também funciona se você multiplicar o número de pessoas chamando e sumarizar seus resultados

Testes distribuídos

Ferramentas como JMeter já oferecem soluções nativas para esses problemas, são os testes distribuídos. Você pode ter um cluster de computadores como slaves da sua origem que está rodando os testes, assim existirão várias instâncias executando o mesmo teste. Recomendo esse artigo que trata desse assunto em específico.

Revisão

Então chegamos ao final. Acredito ter abordado os pontos que considero mais relevantes. Falamos das responsabilidades que cabem a um Teste de Performance, o que eles validam e onde se encontram na Pirâmide de Testes. Abordamos também seus tipos e subtipos, para o que são mais adequados e em que momento aplicá-los. Por último, adentramos ao mundo das ferramentas mais populares, suas capacidades e potenciais, assim como possíveis problemas que podem ser encontrados em sua utilização.
Ainda me sinto na obrigação de reforçar: não crie testes de Performance de forma arbitrária e sempre se pergunte se o cenário em questão  precisa de um teste de Performance .

Agradeço a você que leu até aqui, e nos vemos em uma próxima!