Teste de carga com gafanhoto. Parte 3

Artigo final sobre a ferramenta de teste de estresse Locust. Hoje vou compartilhar as observações que se acumularam no processo. Como sempre, o vídeo está anexado.

Parte 1 - testando com Locust
Parte 2 - Cenários avançados


Entrar


Ao escrever meus primeiros testes com o Locust, fui confrontado com a necessidade de efetuar login em um recurso, depois de receber um token de autorização, que eu usaria posteriormente para testes de carga. Em seguida, surgiu a pergunta - como fazer isso, porque a ferramenta é afiada para enviar todas as solicitações para um recurso, que indicamos no console ao iniciar o teste. Existem várias soluções para o problema:

  • desativando a autorização no recurso testado - se possível
  • gere um token com antecedência e coloque-o no código de teste antes do lançamento - a opção mais fraca, exigindo trabalho manual a cada lançamento, mas com o direito de existir em alguns casos raros
  • envie uma solicitação usando a biblioteca de solicitações e obtenha um token da resposta - bom, a sintaxe é a mesma

Eu escolhi a terceira opção. A seguir, proponho um exemplo refeito do primeiro artigo com diferentes possibilidades de obter um token. O Google.com.br atuará como um servidor de autorização e, portanto,
como não há token, receberei os valores mais simples

from locust import HttpLocust, TaskSet, task import requests class UserBehavior(TaskSet): def on_start(self): response = requests.post("http://mysite.sample.com/login", {"username": "ellen_key", "password": "education"}) # get "token" from response header self.client.headers.update({'Authorization': response.headers.get('Date')}) # get "token" from response cookies self.client.cookies.set('Authorization', response.cookies.get('NID')) # get "token" from response body self.client.headers.update({'Authorization': str(response.content.decode().find('google'))}) 

Como você pode ver no exemplo, antes de iniciar o trabalho, o usuário envia uma solicitação a um servidor de terceiros e processa a resposta, colocando os dados em cabeçalhos ou cookies.

Cabeçalhos


Ao trabalhar com cabeçalhos de solicitação, há várias nuances importantes a serem consideradas.
Para cada solicitação separadamente, você pode especificar seu próprio conjunto de cabeçalhos da seguinte maneira

 self.client.post(url='/posts', data='hello world', headers={'hello': 'world'}) 

Quando o exemplo acima é executado, o cabeçalho hello será adicionado aos cabeçalhos existentes da sessão do cliente, mas somente nesta solicitação não haverá o seguinte. Para tornar o título persistente, você pode adicioná-lo à sessão:

 self.client.headers.update({'aaa': 'bbb'}) 

Outra observação interessante - se na solicitação especificarmos o cabeçalho que já está na sessão - ele será sobrescrito, mas apenas nessa solicitação. Portanto, você não pode ter medo de apagar acidentalmente algo importante.

Mas há exceções. Se precisarmos enviar um formulário com várias partes , a solicitação gerará automaticamente um cabeçalho de Tipo de Conteúdo , que indicará o separador de dados do formulário. Se forçarmos a reescrita do cabeçalho usando o argumento headers , a solicitação falhará porque o formulário não pode ser processado corretamente.

Também é importante notar que todos os cabeçalhos são necessariamente strings. Se você tentar especificar um número, por exemplo {'aaa': 123} , a solicitação não será enviada e o código gerará uma exceção InvalidHeader

Teste distribuído


Para testes distribuídos, o locust fornece vários argumentos da CLI: --master e --slave , para definir claramente as funções. Nesse caso, a máquina com mestre não simulará a carga, mas apenas coletará estatísticas e coordenará o trabalho. Vamos tentar executar nosso servidor de teste e várias sessões no modo distribuído, executando os seguintes comandos em diferentes consoles:

 json-server --watch sample_server/db.json locust -f locust_files\locust_file.py --master --host=http://localhost:3000 locust -f locust_files\locust_file.py --slave --master-host=localhost locust -f locust_files\locust_file.py --slave --master-host=localhost 


Ao abrir gafanhotos no navegador ( localhost: 8089 ), você pode perceber que no canto superior direito temos o número de máquinas que transportarão a carga



Testando sem interface do usuário


Quando todos os testes são escritos e depurados, seria bom incluí-los nos testes automáticos de regressão e apenas verificar periodicamente os resultados. Usando o comando a seguir, você pode executar o teste de gafanhotos sem uma interface do usuário:

 locust -f locust_files\locust_file.py --host=http://localhost:3000 --no-web -c 10 -r 2 --run-time 1m --csv=test_result 

onde

  • --no-web - um argumento que permite executar testes sem uma interface do usuário
  • -c 10 - número máximo de usuários
  • -r 2 - crescimento do usuário por segundo
  • --run-time 1m - tempo de execução do teste (1 minuto)
  • --csv = test_result - após a conclusão do teste, 2 arquivos csv com resultados serão criados na pasta atual, seus nomes começam com test_result

Fatos finais, observações e conclusões


O teste distribuído pode ser combinado com o teste de regressão - para garantir que todos os nós da carga sejam iniciados, você pode adicionar o argumento --expect-slaves = 2 no mestre, caso em que o teste será iniciado apenas quando pelo menos 2 nós forem iniciados.

Me deparei com uma situação algumas vezes - o recurso testado funciona apenas em HTTPS, enquanto o certificado é gerado pelo cliente e o sistema operacional o marca como suspeito. Para que os testes funcionem com êxito, você pode adicionar um argumento a todas as consultas que ignoram a verificação de segurança, por exemplo:

 self.client.get("/posts", verify=False) 

Como nem sempre posso ter certeza em qual ambiente os testes serão executados, sempre indico esse argumento.

Isso é tudo que eu queria compartilhar. Descobri uma ferramenta simples e conveniente, com excelentes recursos de teste e variabilidade na criação de solicitações e processamento de respostas do servidor. Obrigado por ler até o fim.

Source: https://habr.com/ru/post/pt433304/


All Articles