Quando scrivi un software, puoi confermare che funzioni correttamente attraverso test. Per test si intende in linea di massima il processo di esecuzione di un software in una per garantire che funzioni come previsto.
Un test riuscito può darti la sicurezza che, man mano che aggiungi nuovo codice, funzionalità o eseguire l'upgrade delle dipendenze, il software che hai già scritto continuano a funzionare come previsto. I test possono anche contribuire a salvaguardare software contro scenari improbabili o input imprevisti.
Ecco alcuni esempi di comportamenti sul web che potresti voler testare:
- Assicurarsi che la funzionalità di un sito web funzioni correttamente quando viene fatto clic su un pulsante.
- Confermare che una funzione complessa produce i risultati corretti.
- Il completamento di un'azione che richiede l'accesso utente.
- Verificare che un modulo segnali correttamente un errore quando vengono inseriti dati non corretti.
- Assicurarsi che un'app web complessa continui a funzionare anche quando un utente ha se la larghezza di banda è ridotta o passano alla modalità offline.
Test automatici e manuali
Puoi testare il tuo software in due modi generali: con test automatici e manuali test.
I test manuali prevedono l'esecuzione diretta di software da parte di persone fisiche, ad esempio il caricamento di un sito web nel browser e verificando che funzioni come previsto. Manuale sono semplici da creare o da definire. Ad esempio, il tuo sito è in grado di caricarsi? Puoi eseguire queste azioni? Ma ogni operazione ha un costo enorme il tempo dell'uomo. Sebbene le persone siano molto creative, questo può consentire un tipo di test noti come test esplorativi, possiamo comunque riscontrare problemi nel rilevare guasti o incoerenze, soprattutto quando si ripete la stessa attività più volte.
Per test automatico si intende qualsiasi processo che consente di codificare ed eseguire i test ripetutamente da un computer per confermare il comportamento previsto del software senza chiedere a una persona di eseguire passaggi ripetuti, come la configurazione o il controllo dei risultati. È importante sottolineare che, una volta configurato, il test automatico può essere eseguito di frequente. Questa è ancora una definizione molto ampia e vale la pena notare che i modelli i test possono assumere forme e forme di ogni tipo. La maggior parte di questo corso riguarda con i test automatici.
I test manuali hanno il suo posto, spesso come precursore alla scrittura di testi automatizzati ma anche quando i test automatici diventano troppo inaffidabili e di ampio ambito o difficili da scrivere.
Esempio di concetti fondamentali
Per noi, in qualità di sviluppatori web che scrivono codice JavaScript o linguaggi correlati, un breve potrebbe essere uno script come questo, che esegui ogni giorno, magari tramite Node o caricandolo in un browser:
import { fibonacci } from "../src/math.js";
if (fibonacci(0) !== 0) {
throw new Error("Invalid 0th fibonacci result");
}
const fib13 = fibonacci(13);
if (fib13 !== 233) {
throw new Error("Invalid 13th fibonacci result, was=${fib13} wanted=233");
}
Questo è un esempio semplificato che fornisce i seguenti insight:
Questo è un test perché esegue alcuni software (il Fibonacci funzione) e garantisce la sua funziona nel modo previsto confrontandone i risultati con previsti. Se il comportamento non è corretto, si verifica un errore, che JavaScript si esprime generando un
Error
.Anche se lo script è in esecuzione manualmente nel terminale o in browser, questo è ancora un test automatico perché può essere eseguito ripetutamente senza dover eseguire passaggi specifici. La pagina successiva, dove dell'esecuzione dei test, viene spiegato di più.
Anche se questo test non utilizza alcuna libreria, è JavaScript che può eseguirlo ovunque: è comunque un test. Esistono molti strumenti che possono aiutarti scrivere test, inclusi quelli che verranno trattati più avanti in questo corso, continuano a basarsi sul principio fondamentale di "causare un errore" qualcosa va storto.
Test delle librerie nella pratica
La maggior parte delle librerie o dei framework di test integrati fornisce due primitive principali che semplificare la scrittura dei test: asserzioni e un modo per definire test indipendenti. Ne parleremo in dettaglio nella prossima sezione, asserzioni e altre primitive. Tuttavia, a livello generale, è importante ricordare che quasi tutti i test che vedi o scrivi usando questi tipi di primitive.
Le asserzioni sono un modo per combinare il controllo di un risultato e la generazione di un errore se
qualcosa va storto. Ad esempio, puoi rendere il test precedente più conciso
introducendo assert
:
import { fibonacci } from "../src/math.js";
import { assert } from "a-made-up-testing-library";
assert.equal(fibonacci(0), 0, "Invalid 0th fibonacci result");
assert.equal(fibonacci(13), 233, "Invalid 13th fibonacci result");
Se vuoi, puoi migliorare ulteriormente questo test definendo test indipendenti. raggruppate in suite. La suite seguente testa in modo indipendente Fibonacci e la funzione Catalano:
import { fibonacci, catalan } from "../src/math.js";
import { assert, test, suite } from "a-made-up-testing-library";
suite("math tests", () => {
test("fibonacci function", () => {
assert.equal(fibonacci(0), 0, "Invalid 0th fibonacci result");
assert.equal(fibonacci(13), 233, "Invalid 13th fibonacci result");
});
test("relationship between sequences", () => {
const numberToCheck = 4;
const fib = fibonacci(numberToCheck);
const cat = catalan(numberToCheck);
assert.isAbove(fib, cat);
});
});
Nel contesto del test del software, il nome test si riferisce a uno caso di test, ovvero un scenario singolo, indipendente e indirizzabile, come il "rapporto tra sequenze" dell'esempio precedente.
I test con nomi individuali sono utili, ad esempio, per le seguenti attività:
- La determinazione del modo in cui un test ha esito positivo o negativo nel tempo.
- Evidenziazione di un bug o di uno scenario per nome in modo da poter verificare più facilmente che lo scenario è stato risolto.
- Eseguire alcuni test in modo indipendente dagli altri, ad esempio mediante un filtro glob.
Un modo per pensare agli scenari di test è usare le "tre A" del test delle unità: organizzare, agire e dichiarare. In sostanza, ogni scenario di test:
- Disponi alcuni valori o stati (potrebbero essere solo dati di input hardcoded).
- Eseguire un'azione, ad esempio chiamare un metodo.
- Dichiarare i valori di output o lo stato aggiornato (utilizzando
assert
).
L'entità dei test
Gli esempi di codice nella sezione precedente descrivono un test delle unità perché testare parti minori del software, concentrandosi spesso su un singolo file, solo l'output di una singola funzione. La complessità dei test aumenta man mano che prendere in considerazione il codice di più file, componenti o anche diversi (a volte fuori dal tuo controllo, come un servizio di rete o comportamento di una dipendenza esterna). Per questo motivo, i tipi di test vengono spesso denominati in base all'ambito o alla scala.
Oltre ai test delle unità, alcuni esempi di altri tipi di test includono componenti test, test visivi e test di integrazione. Nessuno di questi nomi ha definizioni rigorose e potrebbero avere significati diversi a seconda del tuo del codebase, pertanto ricordati di usarli come guida e di trovare definizioni che lavori per te. Ad esempio, cos'è un componente sottoposto a test nel tuo sistema? Per Reagisci agli sviluppatori: potrebbe essere letteralmente mappato a un "componente React", ma hanno un significato diverso per gli sviluppatori in altri contesti.
La portata di un singolo test può inserirlo all'interno di un concetto spesso definito la "piramide di test", che può essere una buona regola pratica per dei controlli e della loro esecuzione.
Questa idea è stata iterata e varie altre forme sono state popolare, come il diamante di test o il mentre prova un cono di ghiaccio. Le priorità nella scrittura dei test saranno probabilmente specifiche per il tuo codebase. Tuttavia, una funzionalità comune è che i test più semplici, come i test delle unità, sono generalmente più veloci da eseguire, più facili da scrivere (quindi ne avrai di più) e testare un ambito limitato, mentre test complessi come i test end-to-end difficili da scrivere, ma consentono di testare un ambito più ampio. Infatti, il livello superiore di molti test di "shapes" sono generalmente test manuali perché alcune interazioni dell'utente troppo complesso per essere codificato in un test automatico.
Questi tipi verranno ampliati in tipi di modelli test.
Verifica le tue conoscenze
Quali primitive fornisce la maggior parte delle librerie e dei framework di test?
assert()
e le sue varianti tendono a essere incluse perché semplificano i controlli
per scrivere.test()
è incluso in quasi tutti i test
a molti runner. È importante perché il codice di test non viene eseguito al livello superiore
di un file, in modo che l'esecutore del test possa trattare ogni scenario di test come
indipendente.