Test de charge avec criquet. 3e partie

Article final sur l'outil de test de stress acridien. Aujourd'hui, je partagerai les observations qui se sont accumulées au cours du processus. Comme toujours, la vidéo est jointe.

Partie 1 - test avec Locust
Partie 2 - Scénarios avancés


Se connecter


Lors de la rédaction de mes premiers tests avec Locust, j'étais confronté à la nécessité de me connecter à une ressource, d'obtenir un jeton d'autorisation, que j'utiliserais plus tard pour les tests de charge. Ensuite, la question s'est immédiatement posée - comment procéder, car l'outil est affiné pour envoyer toutes les demandes à une ressource, ce que nous indiquons dans la console lors du démarrage du test. Il existe plusieurs solutions au problÚme:

  • dĂ©sactivation de l'autorisation sur la ressource testĂ©e - si possible
  • gĂ©nĂ©rer un jeton Ă  l'avance et le mettre dans le code de test avant le lancement - l'option la plus faible, nĂ©cessitant un travail manuel Ă  chaque lancement, mais ayant le droit d'exister dans de rares cas
  • envoyer une demande en utilisant la bibliothĂšque de demandes et obtenir un jeton de la rĂ©ponse - bon, la syntaxe est la mĂȘme

J'ai choisi la troisiÚme option. Ci-dessous je propose un exemple refait à partir du premier article avec différentes possibilités d'obtention d'un token. Google.com agira comme un serveur d'autorisation et ainsi
comme il n'y a pas de jeton, j'obtiendrai les valeurs les plus 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'))}) 

Comme vous pouvez le voir dans l'exemple, avant de commencer Ă  travailler, l'utilisateur envoie une demande Ă  un serveur tiers et traite la rĂ©ponse, en plaçant les donnĂ©es dans des en-tĂȘtes ou des cookies.

En-tĂȘtes


Lorsque vous travaillez avec des en-tĂȘtes de demande, vous devez prendre en compte plusieurs nuances importantes.
Pour chaque demande sĂ©parĂ©ment, vous pouvez spĂ©cifier votre propre ensemble d'en-tĂȘtes comme suit

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

Lorsque l'exemple ci-dessus est exĂ©cutĂ©, l'en-tĂȘte hello sera ajoutĂ© aux en-tĂȘtes existants de la session client, mais seulement dans cette demande ne sera pas dans tous les suivants. Pour rendre le titre persistant, vous pouvez l'ajouter Ă  la session:

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

Autre observation intĂ©ressante - si dans la requĂȘte nous prĂ©cisons l'en-tĂȘte qui est dĂ©jĂ  dans la session - il sera Ă©crasĂ©, mais uniquement sur cette requĂȘte. Vous ne pouvez donc pas avoir peur d'essuyer accidentellement quelque chose d'important.

Mais il y a des exceptions. Si nous devons envoyer un formulaire en plusieurs parties , la demande gĂ©nĂ©rera automatiquement un en - tĂȘte Content-Type , qui indiquera le sĂ©parateur de donnĂ©es du formulaire. Si nous forçons l'en-tĂȘte Ă  ĂȘtre rĂ©Ă©crit Ă  l'aide de l'argument en- tĂȘtes , la demande Ă©chouera car le formulaire ne peut pas ĂȘtre traitĂ© correctement.

Il convient Ă©galement de noter que tous les en-tĂȘtes sont nĂ©cessairement des chaĂźnes. Si vous essayez de spĂ©cifier un nombre, par exemple {'aaa': 123} , la demande ne sera pas envoyĂ©e et le code lĂšvera une exception InvalidHeader

Tests distribués


Pour les tests distribués, locust fournit plusieurs arguments CLI: --master et --slave , pour définir clairement les rÎles. Dans ce cas, la machine avec maßtre ne simulera pas la charge, mais collectera uniquement des statistiques et coordonnera le travail. Essayons d'exécuter notre serveur de test et plusieurs sessions en mode distribué en exécutant les commandes suivantes dans différentes 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 


En ouvrant Locust dans le navigateur ( localhost: 8089 ), vous pouvez remarquer que dans le coin supérieur droit nous avons le nombre de machines qui porteront la charge



Test sans interface utilisateur


Lorsque tous les tests sont écrits et débogués, il serait intéressant de les inclure dans les tests automatiques de régression et de vérifier périodiquement les résultats. En utilisant la commande suivante, vous pouvez exécuter le test antiacridien sans interface utilisateur:

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

oĂč

  • --no-web - un argument qui vous permet d'exĂ©cuter des tests sans interface utilisateur
  • -c 10 - nombre maximum d'utilisateurs
  • -r 2 - croissance des utilisateurs par seconde
  • --run-time 1m - temps d'exĂ©cution du test (1 minute)
  • --csv = test_result - une fois le test terminĂ©, 2 fichiers csv avec les rĂ©sultats seront crĂ©Ă©s dans le dossier actuel, leurs noms commencent par test_result

Faits, observations et conclusions finales


Les tests distribuĂ©s peuvent ĂȘtre combinĂ©s avec des tests de rĂ©gression - afin de garantir que tous les nƓuds de la charge sont dĂ©marrĂ©s, vous pouvez ajouter l'argument --expect-slaves = 2 sur le maĂźtre, auquel cas le test ne dĂ©marre que si au moins 2 nƓuds sont dĂ©marrĂ©s.

Je suis tombĂ© sur une situation plusieurs fois - la ressource testĂ©e ne fonctionne que sur HTTPS, tandis que le certificat est gĂ©nĂ©rĂ© par le client et que le systĂšme d'exploitation le marque comme suspect. Pour que les tests fonctionnent correctement, vous pouvez ajouter un argument Ă  toutes les requĂȘtes qui ignorent le contrĂŽle de sĂ©curitĂ©, par exemple:

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

Comme je ne peux pas toujours ĂȘtre sĂ»r de l'environnement dans lequel les tests seront exĂ©cutĂ©s, j'indique toujours cet argument.

C'est tout ce que je voulais partager. Pour ma part, j'ai dĂ©couvert un outil simple et pratique avec de grandes capacitĂ©s de test et une grande variabilitĂ© dans la crĂ©ation de requĂȘtes et le traitement des rĂ©ponses du serveur. Merci d'avoir lu jusqu'au bout.

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


All Articles