
Um dos problemas que frequentemente enfrentam os fornecedores de software multi-produto é a duplicação de competências dos engenheiros — desenvolvedores, testadores e administradores de infraestrutura — em quase todas as equipes. Isso também se aplica a engenheiros caros — especialistas em testes de carga.
Em vez de se dedicar às suas funções diretas e usar sua experiência única para estabelecer o processo de testes de carga, escolher metodologias, valores ótimos de métricas e escrever autotestes de acordo com os perfis de carga, os engenheiros muitas vezes precisam montar a infraestrutura de testes do zero, configurar as ferramentas de carga, integrá-las aos sistemas CI, configurar monitoramento e publicar relatórios.
Soluções para alguns problemas organizacionais em testes que utilizamos na Positive Technologies podem ser encontradas em . Neste, falarei sobre a possibilidade de integrar testes de carga ao pipeline CI geral através do conceito de "testes de carga como serviço" (load testing as a service). Você aprenderá como e quais imagens Docker de fontes de carga podem ser usadas no pipeline CI; como conectar fontes de carga ao seu projeto CI usando um modelo de construção; como é o exemplo de pipeline para executar testes de carga e publicar resultados. O artigo pode ser útil para engenheiros de testes de software e engenheiros de automação CI que estão pensando na arquitetura de seu sistema de carga.
A essência do conceito
O conceito de load testing as a service implica a capacidade de integrar ferramentas de carga como Apache JMeter, Yandex.Tank e frameworks próprios em qualquer sistema de integração contínua. O exemplo será para GitLab CI, mas os princípios aqui apresentados são gerais para todos os sistemas CI.
Load testing as a service é um serviço centralizado para a realização de testes de carga. Os testes de carga são executados em pools dedicados de agentes, e a publicação dos resultados ocorre automaticamente no GitLab Pages, Influx DB e Grafana ou em sistemas de relatório de testes (TestRail, ReportPortal etc.). A automação e a escalabilidade são implementadas da forma mais simples possível — por meio da adição e parametrização no projeto GitLab CI de um modelo gitlab-ci.yml padrão.
A vantagem deste approach é que toda a infraestrutura CI, agentes de carga, imagens Docker das fontes de carga, pipelines de teste e publicação de relatórios são mantidos por uma equipe centralizada de automação (engenheiros DevOps), permitindo que os engenheiros de teste de carga se concentrem no desenvolvimento de testes e na análise de seus resultados, sem se preocupar com questões de infraestrutura.
Para simplificar a descrição, vamos considerar que o aplicativo ou servidor alvo a ser testado já está implantado e configurado previamente (para isso podem ser usados scripts automatizados em Python, SaltStack, Ansible, etc.). Assim, toda a conceito de teste de carga como serviço se resume em três etapas: preparação, teste, publicação de relatórios. Para mais detalhes, veja o esquema (todas as imagens são clicáveis):
Conceitos e definições básicas em testes de carga
Ao realizar testes de carga, buscamos seguir , utilizando a terminologia apropriada e métricas recomendadas. Abaixo está uma breve lista de conceitos e definições principais em testes de carga.
Agente de carga (load agent) — uma máquina virtual na qual será executado o aplicativo — fonte de carga (Apache JMeter, Yandex.Tank ou um módulo de carga desenvolvido internamente).
Objetivo do teste (target) — servidor ou aplicativo instalado no servidor que será sujeito à carga.
Cenário de teste (test case) — um conjunto de etapas parametrizadas: ações do usuário e as reações esperadas a essas ações, com solicitações e respostas de rede registradas, dependendo dos parâmetros fornecidos.
Perfil ou plano de carga (profile) — em (p. 4.2.4, p. 43) perfis de carga definem métricas críticas para o teste específico e opções de modificação dos parâmetros de carga durante o teste. Exemplos de perfis podem ser vistos na figura.
Teste (test) — um cenário com um conjunto de parâmetros pré-determinados.
Plano de teste (test-plan) — um conjunto de testes e perfil de carga.
Execução de teste (testrun) — uma iteração de execução de um teste com um cenário de carga completamente realizado e um relatório obtido.
Solicitação de rede (request) — uma solicitação HTTP enviada do agente para o alvo.
Resposta de rede (response) — A resposta HTTP enviada do destino ao agente.
O código de resposta HTTP (status de respostas HTTP) — código padrão de resposta do servidor de aplicações.
Transação — o ciclo completo de "requisição — resposta". A transação é considerada desde o início do envio da requisição até a conclusão do recebimento da resposta.
Status da transação — se o ciclo "requisição – resposta" foi concluído com sucesso. Se ocorrer qualquer erro nesse ciclo, toda a transação é considerada malsucedida.
Tempo de resposta — tempo desde o final do envio da requisição até o início do recebimento da resposta.
Métricas de carga — características definidas durante o teste de carga do serviço sobrecarregado e do agente de carga.
As principais métricas para medir os parâmetros de carga
Algumas das métricas mais comumente utilizadas e recomendadas na metodologia (pág. 36, 52) estão apresentadas na tabela abaixo. Métricas semelhantes para o agente e o destino estão indicadas em uma única linha.
Métricas para o agente de carga
Métricas do sistema ou aplicativo de destino, testados sob carga
Quantidade vCPU e de memória RAM,
Disco — características de hardware do agente de carga
CPU, Uso de memória, uso de disco — dinâmica de utilização da CPU, memória e disco
durante o teste. Normalmente é medido em porcentagens dos
valores máximos disponíveis
Taxa de transferência de rede (no agente de carga) — a largura de banda
da interface de rede no servidor,
onde o agente de carga está instalado.
Normalmente medido em bytes por segundo (bps)
Taxa de transferência de rede(no destino) — largura de banda da interface de rede
no servidor de destino. Normalmente medido em bytes por segundo (bps)
Usuários virtuais— número de usuários virtuais,
realizando cenários de carga e
imitando ações reais de usuários
Status dos usuários virtuais, Aprovado/Falhado/Total — número de status de sucesso e
fracasso dos usuários virtuais
para cenários de carga, assim como seu total.
Normalmente, espera-se que todos os usuários consigam realizar
todas as suas tarefas, conforme especificado no perfil de carga.
Qualquer erro significará que um usuário real também não conseguirá
resolver sua tarefa ao interagir com o sistema.
Requisições por segundo (minuto)— número de requisições de rede por segundo (ou minuto).
Uma característica importante do agente de carga: quantas requisições ele pode gerar.
Na verdade, isso simula a interação com o aplicativo por usuários virtuais
Respostas por segundo (minuto)
— o número de respostas de rede por segundo (ou minuto).
Uma característica importante do serviço alvo: quantas conseguiram
gerar e enviar respostas às solicitações de
agente de carga
Status das respostas HTTP— o número de diferentes códigos de resposta
do servidor de aplicativos, recebidos pelo agente de carga.
Por exemplo, 200 OK significa uma solicitação bem-sucedida,
e 404 — que o recurso não foi encontrado
Latência (tempo de resposta) — o tempo desde o término
do envio da solicitação (request) até o início do recebimento da resposta (response).
Geralmente medido em milissegundos (ms)
Tempo de resposta da transação— o tempo de uma transação completa,
o término do ciclo 'solicitação — resposta'.
Esse é o tempo desde o início do envio da solicitação (request)
até a conclusão do recebimento da resposta (response).
O tempo da transação pode ser medido de várias maneiras: considera-se o mínimo,
máximo, médio e, por exemplo, o 90º percentil.
Os valores mínimo e máximo são os extremos
das condições de desempenho do sistema.
O nonagésimo percentil é usado com mais frequência,
pois mostra a maioria dos usuários,
trabalhando confortavelmente no limite de desempenho do sistema
Transações por segundo (minuto)
— o número de transações completas por segundo (minuto), ou seja, quantas solicitações o aplicativo conseguiu aceitar e
processar e emitir respostas.
Na verdade, isso é a capacidade de processamento do sistema
Status das transações
, Aprovadas / Falhadas / Total — o número
de transações bem-sucedidas, malsucedidas e o total. Para usuários reais, uma transação malsucedida
significará, de fato,
a impossibilidade de trabalhar com o sistema sob carga.
O esquema básico de testes de carga
O esquema básico de testes de carga é muito simples e consiste em três etapas principais, das quais já falei:
Preparar — Testar — Relatar
, ou seja, preparar os objetivos do teste e definir parâmetros para as fontes de carga, em seguida, executar os testes de carga e, por fim, elaborar e publicar o relatório de testes. Notas sobre o esquema:QA.Tester — especialista em testes de carga,
Alvo — aplicativo de destino, para o qual é necessário conhecer seu comportamento sob carga.
- Classificador de entidades, etapas e passos no esquema
- Etapas e passos
O que está acontecendo
Etapas e passos
O que está acontecendo
O que está na entrada
O que está na saída
Prepare: etapa de preparação para testes
LoadParameters
Atribuição e inicialização
pelo usuário
dos parâmetros de carga,
seleção de métricas e
preparação do plano de testes
(perfil de carga)
Parâmetros personalizados para
inicialização do agente de carga
Plano de testes
Objetivo do teste
VM
Implantação em nuvem
de máquina virtual com
as características necessárias
Parâmetros da VM para o agente de carga
Scripts de automação para
criação da VM
VM configurada na
nuvem
Env
Configuração do sistema operacional e preparação
do ambiente para
operar o agente de carga
Parâmetros do ambiente para
o agente de carga
Scripts de automação para
configurações do ambiente
Ambiente preparado:
SO, serviços e aplicativos,
necessários para operação
o agente de carga
LoadAgents
Instalação, configuração e parametrização
do agente de carga.
Ou download da imagem Docker com
fonte de carga pré-configurada
Imagem Docker da fonte de carga
(Yandex.Tank, JM ou estrutura personalizada)
Parâmetros de configuração
o agente de carga
Agente de carga configurado e
pronto para operação
Teste: etapa de execução de testes de carga. As fontes são agentes de carga, implantados em pools dedicados de agentes para GitLab CI
Carga
Início do agente de carga
com o plano de testes selecionado
e parâmetros de carga
Parâmetros personalizados
para inicialização
o agente de carga
Plano de testes
Objetivo do teste
Logs de execução
de testes de carga
Logs do sistema
Dinâmica de alterações nas métricas do objetivo e do agente de carga
RunAgents
Execução pelo agente
de carga dos cenários de teste
de acordo com
perfil de carga
Interação do agente de carga
com o objetivo do teste
Plano de testes
Objetivo do teste
Logs
Coleta de logs 'crus'
durante o teste de carga:
registros das ações do agente de carga,
estado do objetivo do teste
e da VM em que o agente está executando
Logs de execução
de testes de carga
Logs do sistema
Métricas
Coleta de métricas 'cruas' durante o teste
Dinâmica de alterações nas métricas do objetivo
e do agente de carga
Relatório: etapa de preparação do relatório de teste
Gerador
Processamento dos dados coletados
pelo sistema de carga e
sistema de monitoramento das métricas e logs 'crus'
Formação do relatório em
formato legível por humanos,
possivelmente com elementos
de análise
Dinâmica de alterações nas métricas
Logs de execução
de testes de carga
Logs do sistema
do objetivo e do agente de carga
Logs 'crus' processados
em formato adequado para
exportação para armazenamentos externos
Relatório estático sobre a carga,
adequado para análise por humanos
Publicar
Publicação do relatório
sobre os testes de carga em um serviço externo
testando
de carga
em um serviço externo
Logs «crus» processados
em um formato adequado
para exportação para armazenamentos externos
Armazenados em um relatório externo sobre
carga, adequados
para análise humana
Conexão de fontes de carga no modelo CI
Vamos passar para a parte prática. Quero mostrar como em alguns projetos na empresa
Positive Technologies
implementamos a ideia de teste de carga como um serviço. : load. Você pode usar qualquer outra tag compreensível. Elas são definidas
durante o registro dos Runners do GitLab CI. 80% da memória disponível
Assim, com base na nossa experiência, recomendamos que os agentes de carga tenham pelo menos: 4 vCPU, 4 GB de RAM, 60 GB de SSD. A largura de banda da placa de rede é determinada com base nas exigências do perfil de carga. .
Yandex.Tank
é uma ferramenta de código aberto da Yandex para realizar testes de carga. Sua arquitetura modular baseada em um gerador de requisições HTTP assíncrono e de alto desempenho chamado Phantom. O Tank possui monitoramento embutido dos recursos do servidor testado via protocolo SSH, pode automaticamente interromper o teste sob condições especificadas, e pode exibir resultados tanto no console quanto em gráficos; também pode-se conectar seus módulos para expandir a funcionalidade. A propósito, nós utilizamos o Tank quando isso ainda não era um mainstream. No artigo “
” você pode ler a história de como em 2013 realizamos testes de carga com sua ajuda— um dos produtos da nossa empresa. — um dos produtos da nossa empresa.
— é uma ferramenta de código aberto para teste de carga da Apache. Ela pode ser igualmente usada para testar aplicativos web estáticos e dinâmicos. O JMeter suporta uma ampla gama de protocolos e formas de interação com aplicativos: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, etc.), SOAP / REST Webservices, FTP, TCP, LDAP, SMTP(S), POP3(S) e IMAP(S), bancos de dados via JDBC, consegue executar comandos shell e trabalhar com objetos Java. O JMeter possui uma IDE para criar, depurar e executar planos de teste. Também tem uma CLI para operar a partir da linha de comando em qualquer sistema operacional compatível com Java (Linux, Windows, Mac OS X). A ferramenta consegue gerar relatórios HTML dinâmicos sobre o teste.
Para facilitar o uso dentro da nossa empresa, para permitir que os próprios testadores alterem e adicionem ambientes, fizemos builds de imagens Docker para fontes de carga no GitLab CI com publicação em nossa . Isso torna mais rápido e fácil conectá-los em pipelines para testes de carga. Como fazer um docker push em um registry através do GitLab CI — veja em .
O arquivo Docker básico para Yandex.Tank que usamos é este:
Dockerfile
1 | FROM direvius/yandex-tank
2 | ENTRYPOINT [""]E para o Apache JMeter este:
Dockerfile
1 | FROM vmarrazzo/jmeter
2 | ENTRYPOINT [""]Como funciona nosso sistema de integração contínua, você pode ler no artigo “».
Template e pipeline
Um exemplo de template para a realização de testes de carga está disponível no projeto . No você pode ler as instruções para usar o template. No próprio template (arquivo ) há notas sobre o que cada passo ou etapa faz.
O template é muito simples e demonstra três etapas de testes de carga, descritas acima no diagrama: preparação, teste e publicação de relatórios. Para isso são responsáveis : Prepare, Test e Report.
- Etapa deve ser utilizado para a configuração prévia dos objetivos de teste ou verificação de sua disponibilidade. O ambiente para fontes de carga não precisa ser configurado, pois eles já estão prontos como imagens Docker e disponíveis no registry Docker: é suficiente indicar a versão desejada na etapa Test. Mas é possível recompilá-los e criar suas próprias imagens modificadas.
- Etapa é usado para indicar a origem da carga, executar testes e salvar artefatos de teste. Qualquer origem de carga pode ser escolhida: Yandex.Tank, Apache JMeter, ou uma própria, ou todas juntas. Para desativar origens desnecessárias, basta comentar ou remover a job. Pontos de entrada para as origens de carga:
- os parâmetros de execução do Yandex.Tank são especificados no arquivo.,
- os parâmetros de execução do Apache JMeter são especificados no arquivo .
Nota: o modelo de configuração de build é utilizado para configurar a interação com o sistema CI e não se destina a incluir lógica de testes nele. Para os testes, um ponto de entrada é especificado, onde está o script bash controlador. O método de execução dos testes, a geração de relatórios e os próprios cenários de teste devem ser implementados pelos engenheiros de QA. No exemplo demonstrativo, para ambas as origens de carga, um teste simples utiliza uma requisição à página principal do Yandex. Os cenários e parâmetros dos testes estão no diretório .
- Na fase é necessário descrever as formas de publicação dos resultados dos testes obtidos na fase de Teste em repositórios externos, como GitLab Pages ou sistemas de relatórios específicos. Para GitLab Pages, é necessário que, após a conclusão dos testes, o diretório ./public esteja não vazio e contenha pelo menos o arquivo index.html. Você pode ler sobre os detalhes de funcionamento do serviço GitLab Pages .
Exemplos de como exportar dados:
- do JMeter para ,
- do Yandex.Tank para .
Instruções para configurar a publicação:
- HTML estático em ,
- no InfluxDB e depois em .
No exemplo demonstrativo, o pipeline com testes de carga e duas origens de carga (uma delas pode ser desativada) é assim:
Apache JMeter pode gerar automaticamente um relatório HTML, portanto é mais vantajoso salvá-lo no GitLab Pages usando os recursos padrão. Aqui está como o relatório do Apache JMeter se parece:
No exemplo demonstrativo do Yandex.Tank, você verá apenas na seção para GitLab Pages. Durante os testes, o Tank pode salvar resultados no banco de dados InfluxDB, e a partir daí, eles podem ser exibidos, por exemplo, no Grafana (a configuração é feita no arquivo ). Aqui está como o relatório do Tank se apresenta no Grafana:
Resumo
Neste artigo, eu falei sobre o conceito de "teste de carga como serviço" (load testing as a service). A ideia principal é utilizar a infraestrutura de pools de agentes de carga pré-configurados, imagens Docker de fontes de carga, sistemas de relatórios e um pipeline unificador no GitLab CI, baseado em um simples modelo .gitlab-ci.yml (exemplo ). Tudo isso é suportado por uma pequena equipe de engenheiros automatizadores e replicado sob demanda pelas equipes de produto. Espero que isso ajude você na preparação e implementação de um esquema semelhante em sua empresa. Agradeço pela atenção!
P. S. Quero agradecer imensamente aos meus colegas, Sergey Kurbanov e Nikolay Yusev, pela ajuda técnica na implementação do conceito de load testing as a service em nossa empresa.
Autor:: — vice-chefe do departamento de tecnologias e processos de desenvolvimento (DevOps) da Positive Technologies
Fonte: habr.com
