Domanda

So quali sono i vantaggi e utilizzo dati falsi quando lavoro con sistemi più complessi.

Che cosa succede se sto sviluppando qualcosa di semplice e posso facilmente impostare il mio ambiente in un vero database e i dati a cui si accede sono così piccoli che il tempo di accesso non è un fattore e sto solo eseguendo alcuni test.

È ancora importante creare dati falsi o posso dimenticare la codifica aggiuntiva e saltare direttamente alla cosa reale?

Quando ho detto database reale non intendo un database di produzione, intendo un database di prova, ma utilizzo un DBMS reale reale e lo stesso schema del database reale.

È stato utile?

Soluzione

I motivi per utilizzare dati falsi anziché un DB reale sono:

  1. Velocità. Se i tuoi test sono lenti non li eseguirai. Deridere il DB può rendere i test molto più veloci di quanto potrebbero altrimenti.
  2. Controllo. I test devono essere l'unica fonte dei dati dei test. Quando si utilizzano dati falsi, i test scelgono quali falsi verranno utilizzati. Quindi non c'è alcuna possibilità che i tuoi test siano viziati perché qualcuno ha lasciato il DB in uno stato sconosciuto.
  3. Indipendenza dall'ordine. Vogliamo che i nostri test siano eseguibili in qualsiasi ordine. L'input di un test non dovrebbe dipendere dall'output di un altro. Quando i test controllano i dati del test, i test possono essere indipendenti l'uno dall'altro.
  4. Indipendenza ambientale. I test dovrebbero essere eseguibili in qualsiasi ambiente. Dovresti essere in grado di eseguirli mentre sei in treno, in aereo, a casa o al lavoro. Non dovrebbero dipendere da servizi esterni. Quando si utilizzano dati falsi, non è necessario un DB esterno.

Ora, se stai costruendo una piccola piccola applicazione, e usando un DB reale (come MySQL) puoi raggiungere gli obiettivi di cui sopra, allora usa sicuramente il DB. Lo voglio. Ma non commettere errori, man mano che la tua applicazione cresce, alla fine dovrai affrontare la necessità di deridere il DB. Va bene, fallo quando è necessario. YAGNI. Assicurati solo di Farlo QUANDO è necessario. Se lo lasci andare, pagherai.

Altri suggerimenti

Dipende da cosa vuoi testare. Spesso vuoi testare la logica effettiva nel tuo codice e non i dati nel database, quindi impostare un database completo solo per eseguire i test è una perdita di tempo.

Considera anche la quantità di lavoro necessaria per mantenere i tuoi test e database di test. Testare il codice con un database spesso significa che stai testando la tua applicazione nel suo complesso anziché le diverse parti in isolamento. Ciò comporta spesso molto lavoro mantenendo sincronizzati sia il database che i test.

E l'ultimo problema è che il test deve essere eseguito in modo isolato, quindi ogni test deve essere eseguito sulla propria versione del database o lasciarlo esattamente nello stesso stato in cui era prima dell'esecuzione del test. Ciò include lo stato dopo un test fallito.

Detto questo, se vuoi davvero testare sul tuo database puoi farlo. Esistono strumenti che aiutano a creare e distruggere un database, come dbunit .

Ho visto persone che cercavano di creare unit test in questo modo, ma quasi sempre risulta essere molto più lavoro di quanto valga davvero la pena. La maggior parte lo ha abbandonato a metà strada durante il progetto, la maggior parte ha abbandonato completamente il progetto durante il progetto, pensando che il trasferimento dell'esperienza ai test unitari in generale.

Quindi consiglierei di mantenere i test semplici e isolati e incapsulare il codice abbastanza bene che diventa possibile testare il codice in modo isolato.

Penso che dipenda dal fatto che le tue query siano riparate all'interno del repository (l'opzione migliore, IMO) o che il repository esponga query componibili; ad esempio, se si dispone di un metodo di repository:

IQueryable<Customer> GetCustomers() {...}

Quindi la tua UI potrebbe richiedere:

var foo = GetCustomers().Where(x=>SomeUnmappedFunction(x));

bool SomeUnmappedFunction(Customer customer) {
   return customer.RegionId == 12345 && customer.Name.StartsWith("foo");
}

Questo passerà per un repository falso basato su oggetti, ma non riuscirà per le implementazioni db effettive . Naturalmente, è possibile annullare ciò facendo in modo che il repository gestisca tutte le query internamente (nessuna composizione esterna); ad esempio:

Customer[] GetCustomers(int? regionId, string nameStartsWith, ...) {...}

Poiché non è possibile comporlo, è possibile controllare il DB e l'interfaccia utente in modo indipendente. Con le query componibili, sei obbligato a utilizzare i test di integrazione in tutto se vuoi che sia utile.

Dipende piuttosto dal fatto che il DB sia impostato automaticamente dal test, anche se il database è isolato da altri sviluppatori.

Al momento potrebbe non essere un problema (ad esempio un solo sviluppatore). Tuttavia (per l'impostazione manuale del database) la configurazione del database costituisce un ulteriore ostacolo per l'esecuzione dei test, e questa è una cosa molto negativa.

Se stai semplicemente scrivendo una semplice applicazione una tantum che sai che non crescerà, penso che molte delle "migliori pratiche" vai subito fuori dalla finestra.

Non hai bisogno di usare DI / IOC o fare test unitari o deridere il tuo accesso db se tutto ciò che stai scrivendo è un semplice " Contattaci " modulo. Tuttavia, dove tracciare la linea tra un "semplice" app e un "complesso" uno è difficile.

In altre parole, usa il tuo miglior giudizio in quanto non esiste una risposta concreta a questo.

Va ??bene farlo per lo scenario, purché non li vedi come " unit " test. Quelli sarebbero test di integrazione. Devi anche considerare se testerai manualmente l'interfaccia utente più e più volte, poiché potresti semplicemente automatizzare i test del fumo. Detto questo, potresti anche considerare di non eseguire affatto i test di integrazione e di lavorare solo a livello di test funzionali / dell'interfaccia utente (poiché copriranno già l'integrazione).

Come altri hanno sottolineato, è difficile tracciare la linea su complesso / non complesso, e di solito ora quando è troppo tardi :(. Se sei già abituato a farli, sono sicuro che hai vinto ' ottenere molto overhead. Se così non fosse, potresti imparare da esso :)

Per quanto il Real DB non ti ostacoli, e puoi andare più veloce in quel modo, sarei pragmatico e ci proverei.

Nel test unitario, il "test" è più importante dell '"unità".

Supponendo che tu voglia automatizzare questo, la cosa più importante è che puoi generare programmaticamente la tua condizione iniziale. Sembra che sia così, e ancora meglio stai testando i dati del mondo reale.

Tuttavia, ci sono alcuni svantaggi:

Il tuo vero database potrebbe non coprire determinate condizioni nel tuo codice. Se disponi di dati falsi, causi questo comportamento.

E come fai notare, hai una semplice applicazione; quando diventa meno semplice, ti consigliamo di avere test che puoi classificare come unit test e test di sistema. I test unitari dovrebbero riguardare una semplice funzionalità, che sarà molto più facile da fare con dati falsi.

Un vantaggio dei repository falsi è che il test di regressione / unità è coerente poiché puoi aspettarti gli stessi risultati per le stesse query. Ciò semplifica la creazione di determinati test unitari.

Ci sono diversi svantaggi se il tuo codice (se non solo read-query) modifica i dati: - Se si verifica un errore nel codice (che probabilmente è il motivo per cui si sta eseguendo il test), si potrebbe finire per rompere il database di produzione. Anche se non l'hai rotto. - se il database di produzione cambia nel tempo e specialmente durante l'esecuzione del codice, è possibile che si perda traccia dei materiali di test aggiunti e si risulti difficile ripulirlo dal database. - Le query di produzione da altri sistemi che accedono al database possono trattare i dati dei test come dati reali e questo può corrompere i risultati di importanti processi aziendali da qualche parte lungo la strada. Ad esempio, anche se hai contrassegnato i tuoi dati con un determinato flag o prefisso, puoi assicurarti che chiunque acceda al database aderirà a questo schema?

Inoltre, alcuni database sono regolati dalle leggi sulla privacy, quindi a seconda del contratto e di chi possiede il DB principale, è possibile o meno essere legalmente autorizzati ad accedere a dati reali.

Se è necessario eseguire un database di produzione, si consiglia di eseguire una copia che è possibile creare facilmente durante le ore di punta.

È un'applicazione davvero semplice e non puoi vederla crescere, non vedo problemi nell'esecuzione dei test su un DB reale. Se, tuttavia, ritieni che questa applicazione cresca, è importante che tu ne tenga conto nei tuoi test.

Mantieni tutto il più semplice possibile e, se in seguito hai bisogno di test più flessibili, fallo. Pianifica in anticipo, però, perché non vuoi avere un'applicazione enorme in 3 anni che si basa su test vecchi e confusi (per un'applicazione di grandi dimensioni).

L'aspetto negativo dell'esecuzione di test sul database è la mancanza di velocità e la complessità per l'impostazione dello stato del database prima di eseguire i test.

Se si ha il controllo su questo non vi è alcun problema nell'esecuzione dei test direttamente sul database; è in realtà un buon approccio perché simula il tuo prodotto finale meglio che correre contro dati falsi. La chiave è avere un approccio pragmatico e vedere le migliori pratiche come linee guida e non regole.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top