Come creare dati di input per unit test per un client API?
Sto creando la serie iniziale di unit test per il sistema client API legacy del mio team. Abbiamo scritto test di integrazione, ma non abbiamo test unitari.
È un Sinatraserver che accetta le richieste dalla nostra app web e contatta le API di terze parti. A volte restituisce il risultato all'app Web.
1 2
(Web app) ---> Server endpoints ---> API Client class ---> 3rd party API
<--- <--- <---
3
Trattandosi di un sistema legacy, sto pensando di scrivere test di caratterizzazione . Proverò quanto segue:
- deridere i nostri metodi di classe API Client, per verificare come i dati di input agli endpoint del server vengono elaborati e formattati quando raggiungono i nostri metodi di classe API Client.
- Allo stesso modo simula (o inietta) la chiamata all'API di terze parti, per verificare come i dati di input al metodo della classe API Client vengono elaborati e formattati quando raggiunge la chiamata API di terze parti.
- Restituisci le risposte predefinite del server, per verificare come il nostro programma risponde ed elabora ogni risposta.
Poiché i test saranno test di caratterizzazione, userò solo l'output generato dal codice eseguito dal test runner.
Non sono sicuro di come generare input. I payload sono oggetti piuttosto complessi, che possono avere ~ 30 campi (parametri) per alcuni endpoint.
Non credo sia realistico testare tutte le possibili combinazioni di parametri di input. Ecco il mio piano:
- Per ogni test, crea un input di test il più tipico possibile utilizzando il carico utile reale. Salvalo in un file, come dispositivo.
- Identifica alcuni campi che sono interessanti, importanti o che hanno precedentemente causato errori. Crea scenari di test per questi campi. Caricare il dispositivo e, in ogni caso di test, sovrascrivere un campo nel carico utile con un valore estremo, un valore limite o un valore illegale e fare affermazioni con ogni carico utile. Ad esempio, se il campo A deve essere compreso tra 5 <A <15, con A = 5, A = 15, A = 4, A = 14, A = nil, ecc.
- Eseguire il test con valori attesi non riusciti. Copia l'output effettivo dal test runner, incollalo nei valori previsti.
Non sono sicuro che 1. questo sia il modo corretto di eseguire i test di caratterizzazione e 2. questo sia un buon modo per creare dati di input di test. Sto esagerando? O lo stai facendo completamente sbagliato?
Risposte
Sei decisamente sulla strada giusta qui.
Inizierei raccogliendo richieste e risposte effettive generate dal sistema live, quindi anonimizzerei se necessario. Questi sarebbero i semi dei tuoi test, poiché avrebbero il formato corretto. Dovrebbero essere disponibili nei log dell'applicazione, anche se potrebbe essere necessario farlo utilizzando l'applicazione Web per effettuare le richieste da soli.
Raccogliendo un set iniziale di dati dal sistema reale, avrai qualcosa che puoi modificare come hai suggerito.
AGGIORNAMENTO (in risposta al commento dell'OP):
Con la dimensione delle richieste (fino a 30 parametri), l'utilizzo di dati reali ti consentirà anche di avere un'idea dei parametri più comunemente utilizzati e del tipo di dati che l'utilizzo nel mondo reale ti darà.
Ciò consente di generare i dati di test tenendo conto sia della regola 80/20 (il 20% dell'applicazione ottiene l'80% dell'utilizzo) sia dei rischi (i guasti più potenzialmente dannosi).
Analizzerei i dati del test per decidere quali sono gli scenari più comuni e iniziare imitando quelli come la mia prima priorità. La mia seconda priorità sarebbero le parti a più alto rischio del sistema. Dopodiché, lavoravo attraverso un mix di scenari meno comuni e rischi inferiori finché non avevo una copertura che mi soddisfaceva.
La cosa importante da ricordare con questo tipo di automazione e test è che non sarai mai "finito". Hai troppe potenziali combinazioni di dati ed endpoint per coprirli tutti. Il tuo obiettivo dovrebbe essere quello di coprire prima gli scenari di rischio più comuni e più alti, quindi continuare ad aggiungerne altri finché i problemi che non vengono rilevati dall'automazione diventano estremamente rari.