Ho creato uno scenario in cui ho due funzioni, A e B, entrambe sono testate, ma nonostante i test ho comunque iniettato un bug piuttosto stupido e alcuni dati non entrano nel database. Si noti che non è presente ORM. Ho scritto le mie operazioni CRUD direttamente, e sto pagando il prezzo per questo.
In questo scenario, ho (perl) qualcosa del genere:
sub A {
... do a bunch of work ...
my $res = B( %data );
... do a bunch more work ...
}
sub B {
my ( %data ) = @_;
... record data to the database and return a result ...
}
Ciò che è successo, però, è che nella mia applicazione di livello superiore e in A stesso, ho cambiato il nome di uno dei campi che va in% dati, ma ho dimenticato di cambiarlo in B. Ho un test per A quale stub / prende in giro un lotto delle cose che A fa (A deve soddisfare un buon refactoring), incluso B. Lo stub per B verifica che tutti i parametri corretti, compresi i nomi dei campi corretti passare in, e così passa il test.
MA il test per B verifica i vecchi nomi di campo, la vera B usa effettivamente i vecchi nomi di campo e anche quel test passa.
E, quindi, ho messo in produzione del codice che, a causa di questa svista, sta inserendo NULL nel database in cui non desidero i NULL.
- A è chiaramente troppo grande. Per isolarlo, sto prendendo in giro sei diverse funzioni, ognuna delle quali potrebbe causare un cambiamento di stato del sistema.
- A, e quindi il test per A è teoricamente indifferente alla strategia con cui B memorizzerà i dati nel database o anche a quale tipo di database B memorizzerà i dati, quindi penso che il test per A probabilmente non dovrebbe interrogare il database direttamente.
- Ma ho cambiato il formato di% di dati e penso che il test per A avrebbe dovuto rilevare che sostanzialmente ho cambiato l'API senza propagare la modifica.
Quale è un modo migliore per impostare un test per rilevare questo caso in anticipo?
- Continua con la strategia di isolamento per A e B, ma scrivi anche un'integrazione che testa A - alla maniera di > il database? Ciò porterebbe a una proliferazione di possibili casi di test, e sto già avendo difficoltà a giustificare la gestione del caso di proliferazione al caso (anche se so che la copertura è dolorosamente inadeguata).
- Basta scrivere il test per A per interrogare il database, possibilmente attraverso un'astrazione?
- C'è qualcosa di diverso che potrebbe aiutarti qui?
In definitiva, ho seguito il suggerimento di Karl Bielefeldt. Ho aggiunto il codice di convalida dei dati nella funzione B. Ho anche aggiunto il test di integrazione che controlla da A fino al DB.
Per quanto posso dire, ho bisogno di avere quanti più test di integrazione possibili, verificando che lo stato generale delle risorse di sistema cambi in modo prevedibile. Allo stesso tempo, prevedo che avrò ancora bisogno di prendere in giro le risorse di rete se non riesco a ottenere un ambiente di rete di test.