Cerca di seguire la struttura di assetto-atto-assert per ogni test.
- Disporre i tuoi oggetti ecc. e metterli in uno stato noto (un dispositivo di prova). A volte, questa fase include affermazioni per dimostrare che sei effettivamente nello stato che pensi di essere.
- Agisci, ovvero: esegui il comportamento che stai testando.
- Asserisci di aver ottenuto il risultato previsto.
I test non si preoccupano di creare prima uno stato conosciuto, quindi sono privi di significato isolati.
Inoltre, i test unitari non testano necessariamente un solo metodo - i test unitari dovrebbero testare un'unità. Di solito, questa unità è una classe. Alcuni metodi come get()
hanno senso solo in combinazione con un altro.
Il collaudo di getter e setter è ragionevole, in particolare nei linguaggi dinamici (solo per assicurarsi che siano effettivamente lì). Per testare un getter, dobbiamo prima fornire un valore conosciuto. Questo potrebbe accadere attraverso il costruttore o attraverso un setter. O visto in modo diverso: testare il getter è implicito nei test del setter e del costruttore. E il setter, restituisce sempre true
, o solo quando il valore è stato cambiato? Questo potrebbe portare ai seguenti test (pseudocodice):
describe Api:
it has a default value:
// arrange
api = new Api()
// act & assert
assert api.get() === expected default value
it can take custom values:
// arrange & act
api = new Api(42)
// act & assert
assert api.get() === 42
describe set:
it can set new values:
// arrange
api = new Api(7)
// act
ok = api.set(13)
// assert
assert ok === true:
assert api.get() === 13
it returns false when value is unchanged:
// arrange
api = new Api(57)
// act
ok = api.set(57)
// assert
assert ok === false
assert api.get() === 57
Riutilizzare lo stato di un test precedente renderebbe i nostri test abbastanza fragili. Riordinare i test o modificare il valore esatto in un test potrebbe causare il fallimento di test apparentemente non correlati. Supponendo che uno stato specifico possa anche nascondere i bug, se causa il superamento dei test, questo dovrebbe effettivamente fallire. Per evitare ciò, alcuni runner di test hanno opzioni per eseguire i test case in un ordine casuale.
Tuttavia, ci sono casi in cui riutilizziamo lo stato fornito dal test precedente. In particolare, quando la creazione di un dispositivo di prova richiede molto tempo, combiniamo molti casi di test in una suite di test. Sebbene questi test siano più fragili, potrebbero essere ancora più preziosi ora perché possono essere eseguiti più rapidamente e più spesso. In pratica, la combinazione di test è auspicabile ogni volta che i test coinvolgono un componente manuale, quando è necessario un database di grandi dimensioni o quando si testano le macchine a stati.