Come utilizzare Python per testare il carico dei siti web

Immagina di avere una nuova applicazione web e di sapere che si comporta bene con un piccolo gruppo di utenti. Ma come risponderebbe la tua applicazione all’aumento del traffico che supera il carico previsto? Esegui un test di carico sulla tua applicazione web con Python!

In questo articolo, imparerai come eseguire un test di carico su un’applicazione web simulando centinaia di utenti che accedono contemporaneamente alla tua applicazione.

Continua a leggere per iniziare a testare il carico sui siti web!

Prerequisiti

Questo tutorial sarà una dimostrazione pratica. Se vuoi seguirci, assicurati di avere quanto segue:

Configurazione di un Sito Web Statico

Prima di eseguire un test di carico su un sito web, devi prima configurare un sito demo. Creerai un sito web statico e un’API demo per questo tutorial, ma qui ti concentrerai prima sul sito web statico. Un sito web statico ti mostrerà i concetti di base del test di carico, mentre un’API ti mostrerà come passare diversi parametri per simulare diverse operazioni.

Se preferisci iniziare a eseguire il test di carico su un’API, puoi passare alla sezione successiva, dove installerai Locust e lo eseguirai sul tuo computer. Le demo in questo tutorial utilizzano l’API demo Swagger Petstore.

  1. Crea un nuovo file nel tuo editor di codice preferito, copia il codice qui sotto nel nuovo file e salvalo con il nome che preferisci. Per questo esempio, il file si chiama load_test_page.html.

Di seguito è riportato un documento HTML, che mostra il testo “Questa è una pagina di prova.” quando viene aperto su un browser web.

<!DOCTYPE html>
<html>
	<head>
		<title>ATA Load Balancing Demo</title>
	</head>
	<body>
		<h1>This is a test page.</h1>
	</body>
</html>

2. Successivamente, apri il tuo browser web preferito e vai al tuo account di archiviazione nel Portale di Azure.

3. Segui i passaggi seguenti per abilitare l’hosting del sito web statico all’interno di un account di archiviazione e impostare la pagina principale del tuo sito web:

  • Clicca su sito web statico sul pannello di navigazione a sinistra. La pagina del sito web statico è dove caricherai i file per il tuo sito dimostrativo.
  • Clicca su Abilitato, come mostrato di seguito, per abilitare l’hosting del sito web statico.
  • Inserisci load_test_page.html nel campo Nome del documento indice, e clicca su Salva. In questo modo verrà creato automaticamente un contenitore di blob e un URL (endpoint primario), che punta al tuo sito web. L’URL non funzionerà ancora, ma conservalo per dopo.
Enabling Static Website Hosting

4. Clicca su Esploratore di archiviazione (anteprima) nel pannello di sinistra e vai a Contenitori di blob → $web. Il contenitore di blob $web, creato dalla funzione del sito web statico, ospiterà tutti i tuoi file statici.

Clicca su Carica, e quindi carica il load_test_page.html che hai creato nel primo passaggio.

Uploading Static Files (HTML Page)

5. Infine, apri una nuova scheda sul tuo browser web, vai all’URL che hai annotato nel secondo passaggio e verifica se l’URL funziona ora.

Accessing Static Website’s URL

Installazione del Framework Locust

Ora hai un sito da testare, ma hai ancora bisogno di strumenti di test di carico per testare il tuo sito web. Scrivere il tuo codice per gestire i test di carico elevati è dispendioso in termini di tempo e soggetto a errori. Perché non utilizzare il framework Locust? Locust è uno strumento open-source scritto in Python che puoi installare tramite il gestore dei pacchetti pip.

Se hai bisogno di rinfrescare le tue conoscenze su Python, dai un’occhiata a Funzioni Python per principianti.

Locust può eseguire test di carico su siti statici, applicazioni web o addirittura API. L’unico requisito è che ciò che stai testando abbia un endpoint HTTP(S) a cui puoi accedere dal tuo dispositivo.

Per impostazione predefinita, il gestore di pacchetti pip installa i pacchetti nella directory ~/.local su Linux e MacOS, che non è nel percorso di sistema. Quel percorso è disponibile solo per un ambiente virtuale Python, motivo per cui userai pip in questo tutorial.

  1. Apri il terminale e esegui i comandi qui sotto per creare un nuovo ambiente virtuale e installare Locust.
# Utilizza il modulo venv per creare un nuovo ambiente virtuale Python
python3 -m venv venv 
# Attiva l'ambiente virtuale
source venv/bin/activate 
# Installa Locust nel nuovo ambiente virtuale
python3 -m pip install locust
Starting and installing locust in a virtual environment

2. Esegui i comandi qui sotto per creare la nuova directory e navigare fino ad essa. Farlo mantiene i file di locust isolati dal resto della tua base di codice, rendendo più facile organizzare. Per questo esempio, la directory è chiamata locust_dir.

mkdir locust_dir
cd locust_dir

3. Infine, crea un nuovo file chiamato locustfile.py nella directory locust_dir, quindi copia/incolla il codice qui sotto nel file locustfile.py. Questo file conterrà le tue istruzioni di test, come simulare gli utenti, quali endpoint quegli utenti colpiranno e quali parametri passare.

Quando Locust viene eseguito, cerca un file specifico chiamato locustfile.py. Quindi è meglio salvare quel file in una directory separata (locust_dir), consentendo a Locust di trovarlo, e puoi creare test aggiuntivi senza sovrascrivere altri test.

Il codice sottostante esegue una richiesta HTTP GET al percorso dell’hostname che fornisci, equivalente a eseguire curl http://<Host>/ dalla riga di comando.

Una volta ricevuta una risposta, Locust invia immediatamente la richiesta successiva, e l’intero processo si ripete per ogni utente virtuale nel test.

# Importa classi da Locust
from locust import HttpUser, task 

# Istanzia un nuovo utente virtuale
class HelloWorldUser(HttpUser): 
    # Questo dice a locust di trattare il metodo sottostante 
    # come qualcosa che l'utente virtuale farebbe
    @task 
    # Definisci un nuovo metodo
    def hello_world(self): 
        # Questo metodo eseguirà una richiesta HTTP GET sul percorso `/` 
        # del sito che stai testando
        self.client.get("/") 

Se il percorso nel metodo sembra incompleto, è perché lo è. Solo il percorso e i parametri di query sono definiti in un file di locust, mentre l’host viene passato durante l’esecuzione. Questo metodo avrà più senso nel prossimo passo.

Eseguire un Test di Carico Contro Siti Statici

Ora che hai installato Locust, è il momento di eseguire un test di carico! Il test di carico non riguarda solo la scrittura di una serie di richieste web per vedere cosa fa la tua applicazione. Un test completo registra i tempi di risposta, i tassi di errore e i codici di errore su diversi endpoint e configurazioni.

Locust è flessibile nell’esecuzione in quanto può essere chiamato da riga di comando o tramite un’interfaccia web. Per questo tutorial, utilizzerai l’interfaccia web per eseguire un test di carico contro un sito statico.

Esegui il comando locust per avviare l’applicazione grafica di locust utilizzando lo scenario di test dal tuo file locustfile.py.

locust 
Run the locust command

2. Apri un browser web e vai su http://localhost:8089/ per accedere a Locust. La porta 8089 è la porta predefinita su cui viene eseguito Locust.

Ricorda l’URL (endpoint principale) che hai annotato al terzo passaggio nella sezione “Configurazione di un Sito Web Statico”? Ora è il momento di utilizzarlo nel passaggio successivo!

3. Infine, inserisci l’URL (endpoint principale) nel campo Host visto nello screenshot qui sotto, quindi clicca Avvia sciamatura per avviare il test di carico. In questo modo dici a tutti i test nel tuo file locustfile.py di eseguire contro l’URL che hai inserito nel campo Host.

Per questa demo, cambiare il valore del campo Numero di utenti o del campo Tasso di spawn è facoltativo.

Il Numero di utenti è il numero massimo di utenti virtuali da creare contemporaneamente. Allo stesso tempo, il Tasso di spawn è il numero di utenti creati ogni secondo fino a quando Locust raggiunge la massima concorrenza di utenti virtuali. Il numero di utenti virtuali rimane al massimo fino a quando non si interrompe il test.

Running Locust load test on localhost:8089

Mentre esegue i test, Locust aggiunge l’host, quindi invia una richiesta a ciascun percorso nella classe utente in tempo reale. Una volta ricevuta una risposta, Locust invia immediatamente un’altra.

Vedrai un elenco degli endpoint testati di seguito, oltre a alcune statistiche sui tempi di risposta, sui fallimenti e sulle richieste al secondo.

Viewing Locust Chart Showing the Number of Requests, Failures, and Response Times for the Test Case

Se preferisci visualizzare le metriche delle prestazioni del tuo sito web in un’uscita grafica, come mostrato di seguito, fai clic sulla scheda Grafici.

Viewing graphical output of load tests statistics

Eseguire un Test di Carico Contro le API

Ora che sei familiare con i concetti di base di Locust, diamo un’occhiata a un caso di test più realistico. Un sito statico è piuttosto stabile e non c’è molto che possa andare storto durante i test di prestazioni. Quindi perché eseguire un test di carico contro un’API?

Un’API può avere molta più variabilità nelle risposte, opzioni di hosting meno stabili e molto più impatto potenziale per la tua organizzazione se si verificano tempi di inattività.

Se non sei familiare con le API e come funzionano, c’è un articolo che spiega concetti di base come l’autenticazione, i metodi HTTP e le risposte JSON. L’articolo è destinato a PowerShell, ma i concetti delle API saranno importanti più avanti in questo articolo.

  1. Sostituisci il contenuto del file locustfile.py con il codice qui sotto, che fa alcune cose:
  • Esegue una richiesta GET per autenticare l’utente quando Locust istanzia un nuovo utente virtuale
  • Esegue una richiesta GET sull’host, che fallirà perché quella risorsa non esiste
  • Esegue una richiesta POST che passa un corpo JSON su una serie di elementi nello stesso endpoint.
import time # Importa il tempo dalla libreria di sistema Python
from locust import HttpUser, task

class HelloWorldUser(HttpUser):

    # Questo compito verrà eseguito quando l'utente è istanziato
		def on_start(self): 
        # La API del petstore non ha un database utenti,
        # quindi qualsiasi nome utente e password funzioneranno
        username = "foo" 
        password = "bar"
        # Questo deve conformarsi all'endpoint loginUser dalla documentazione API
        self.client.get("/user/login?username="+username+"&password="+password) 

    # Questo compito fallirà perché non c'è nessun endpoint su https://petstore.swagger.io/v2/
    @task
    def hello_world(self): 
        self.client.get("/")

    # Il (3) dopo il decoratore del compito dice a Locust di eseguire questo compito 3 volte più spesso
    @task(3) 
    def update_pets(self):
        # Usando un ciclo for, conta da 0 a 4 e utilizzalo nella richiesta HTTP qui sotto
        for pet_id in range(5): 
            # Esegui richiesta HTTP POST e passa un Corpo JSON
            self.client.post(f"/pet?petId={pet_id}", json={"name":"Mittens"}) 
            time.sleep(1) # Aspetta 1 secondo prima di continuare 

Senza aggiungere una dichiarazione on_start alla tua classe di test, gli altri metodi restituirebbero un errore “403 Non autorizzato” quando Locust tenta di testarli. Prova a commentare questo metodo e a eseguire nuovamente Locust per vedere come influisce sul test.

2. Successivamente, apri la documentazione per l’API del negozio di animali domestici. Il caso di test sopra è scritto specificamente per questa API, quindi avere questa pagina aperta accanto a questo tutorial ti aiuterà a passare attraverso gli endpoint.

Esegui il comando locust di seguito come hai fatto nella sezione “Esecuzione di un test di carico contro siti statici” (passaggio uno).

locust
Run the locust command

Infine, inserisci https://petstore.swagger.io/v2 come host nell’interfaccia utente di Locust.

Viewing endpoints of pet store API being tested

Conclusione

In questo tutorial, hai imparato come eseguire un test di carico su un sito web statico e un’API. Ora hai un’idea migliore di come testare il tuo sito per un grande afflusso di utenti. I test di carico sono utili quando si prepara un’applicazione per il rilascio ai clienti. Lo stesso vale per la configurazione di auto-scaling o le prestazioni dell’applicazione per la bassa latenza.

Ora pensa alle tue applicazioni attuali o a quelle che supporti. Come risponderebbero quando uno sciame di utenti concorrenti lo sta utilizzando? Quali tipi di cose pensi possano evidenziare gli scenari di test di carico per migliorare le prestazioni della tua applicazione?

Source:
https://adamtheautomator.com/load-test/