2009-05-09 14 views
41

Di solito mi imbatto in questo problema e non sono sicuro di come superare questo ostacolo. Voglio davvero iniziare ad imparare e ad applicare Test-Driven-Development (o BDD, o qualsiasi altra cosa) ma sembra che ogni applicazione che faccio dove voglio applicare sia praticamente solo roba di database standard CRUD, e non sono sicuro di come per applicarlo. Gli oggetti praticamente non fanno nulla oltre a essere persistenti in un database; non c'è una logica complessa che deve essere testata. C'è un gateway che alla fine avrò bisogno di testare per un servizio di terze parti, ma voglio ottenere prima il nucleo dell'applicazione.Applicazione di TDD quando l'applicazione è al 100% CRUD

Ogni volta che provo a scrivere test, finisco solo per testare cose di base che probabilmente non dovrei testare in primo luogo (ad esempio getter/setter) ma non sembra che gli oggetti abbiano qualcos'altro. Immagino di poter testare la persistenza, ma questo non mi sembra mai giusto perché non dovresti colpire un database, ma se lo prendi in giro non testerai nulla perché controlli i dati che vengono restituiti; come ho visto molti esempi in cui esiste un repository simulato che simula un database eseguendo il ciclo e creando un elenco di valori noti, e il test verifica che il "repository" possa recuperare un determinato valore ... non vedere il punto di un test come questo perché ovviamente il "repository" restituirà quel valore; è hard-coded nella classe! Bene, lo vedo da un punto di vista TDD puro (cioè è necessario avere un test che dice che il repository ha bisogno di un metodo GetCustomerByName o qualsiasi altra cosa prima di poter scrivere il metodo stesso), ma sembra seguire il dogma senza una ragione diversa dal suo " il modo "- il test non sembra fare nulla di utile oltre a giustificare un metodo.

Sto pensando a questo nel modo sbagliato?

Ad esempio, eseguire una corsa dell'applicazione di gestione dei contatti del mulino. Abbiamo contatti e diciamo che possiamo inviare messaggi ai contatti. Abbiamo quindi due entità: Contact e Message, ciascuna con proprietà comuni (ad esempio Nome, Cognome, Email per il contatto, Oggetto e corpo e Data per messaggio). Se nessuno di questi oggetti ha un comportamento reale o è necessario eseguire alcuna logica, come si applica TDD quando si progetta un'app in questo modo? L'unico scopo dell'applicazione è essenzialmente quello di estrarre un elenco di contatti e visualizzarli su una pagina, visualizzare un modulo per inviare un messaggio e simili. Non sto vedendo nessun tipo di test utili qui - potrei pensare ad alcuni test ma sarebbero praticamente dei test per il gusto di dire "Vedi, ho degli esami!" invece di testare un qualche tipo di logica (sebbene Ruby on Rails ne faccia buon uso, non ritengo che la validazione dei test sia un test "utile" perché dovrebbe essere qualcosa che il framework si prende cura di voi)

+14

Devo solo dire ... I * love * il titolo di questo domanda. – Shog9

+1

Questa è una domanda molto buona. Credo che la maggior parte delle volte, quando ascoltiamo argomentazioni sulla giustificazione dei costi del TDD, in realtà parlano specificamente di applicazioni simili a CRUD. – Sake

+4

Questo è quello che ho notato anche io.Voglio * usare * TDD (beh non necessariamente TDD, ma testare) ma non riesco mai a pensare a cosa testare quando l'app ha solo bisogno di estrarre dati - ho ottenuto alcune risposte fantastiche qui, però. –

risposta

14

"L'unico scopo dell'applicazione è essenzialmente quello di estrarre un elenco di contatti"

OK. Provalo. Cosa significa "tirare"? Sembra "logica".

"visualizzarli in una pagina"

Va bene. Provalo. Quelli giusti visualizzati? Tutto lì?

"visualizzare un form per inviare un messaggio,"

Va bene. Provalo. Campi giusti? Le convalide degli input funzionano tutte?

"e simili".

OK. Provalo. Le query funzionano? Trova i dati giusti? Mostra i dati giusti? Convalidare gli input? Produce i giusti messaggi di errore per gli input non validi?

+0

@ S.Lott Che cosa stai descrivendo qui è più test di tipo comportamentale a livello di unità rispetto a TDD. Sono d'accordo sul fatto che ciascuna delle aree che hai menzionato sono i primi candidati per i test unitari. –

+0

Se definiscono "pull" in forma testabile, i test guidano il design di "pull". Se definiscono "visualizzarli su una pagina" in termini di risultati verificabili, i test guidano la progettazione di "display". Mi sembra TDD. –

+0

Sono d'accordo che finchè i test guidano il design e non testano il comportamento. –

1

Vedo quello che stai dicendo, ma alla fine i tuoi modelli diventeranno sufficientemente avanzati da richiedere (o essere notevolmente aumentati da) test automatici. In caso contrario, ciò che stai essenzialmente sviluppando è un foglio di calcolo che qualcuno ha già sviluppato per te.

Dal momento che hai menzionato Rails, direi che fare un test standard di creazione/lettura/aggiornamento/eliminazione è una buona idea per ogni proprietà, soprattutto perché il test dovrebbe annotare le autorizzazioni (questo è enorme penso). Ciò garantisce anche che le migrazioni funzionino come previsto.

+0

Non sto usando Rails, ma l'ho usato come esempio perché ha "rodato" i test e questo è quello che i tutorial normalmente dicono che dovresti testare. Vedo il tuo punto. –

5

Sto lavorando su un'applicazione CRUD puro momento Ma vedo un sacco di vantaggi di casi di test di unità (Nota: non ho detto TDD)

scrivo codice prima e poi i casi di test - ma mai troppo distanti - abbastanza presto però

E provo le operazioni CRUD - Persistenza anche nel database.

Quando ho finito con la persistenza - e passare al livello dell'interfaccia utente - avrò una buona dose di fiducia che il mio livello di servizio \ persistenza è buono - e posso quindi concentrarmi solo sull'interfaccia utente in quel momento.

Quindi IMHO- c'è sempre vantaggio di test TDD \ Unità (come si chiamano a seconda di come estremo ci si sente su di esso) - anche per l'applicazione CRUD Hai solo bisogno di trovare la giusta strategia per- vostra applicazione

Basta usare il buon senso ... e starai bene.

1

Attualmente sto lavorando a un'applicazione CRUD. Quello che sto facendo a questo punto è la scrittura di unit test sui miei oggetti Repository e testare che le funzionalità CRUD funzionino come dovrebbero. Ho scoperto che questo ha intrinsecamente testato l'effettivo codice del database. Abbiamo trovato alcuni bug nel codice del database in questo modo. Quindi ti suggerisco di andare avanti e andare avanti con i test unitari. So che applicare TDD sulle app CRUD non è così affascinante come le cose che potresti leggere su blog o riviste, ma sta servendo il suo scopo e tu sarai molto meglio quando lavorerai su un'applicazione più complessa.

2

Solo un'idea ...

Prendere i requisiti per il CRUD, utilizzare strumenti come watij o watir o AutoIt per creare casi di test. Inizia a creare l'interfaccia utente per superare i casi di test. Una volta che l'interfaccia utente è salita e passa forse un solo test, inizia a scrivere il livello logico per quel test e poi il livello db.

Per la maggior parte degli utenti, l'interfaccia utente è il sistema. Ricorda di scrivere casi di test per ogni nuovo livello che stai costruendo. Quindi, invece di iniziare dal db all'app al livello ui, inizia nella direzione opposta.

Alla fine della giornata, probabilmente avresti accumulato un potente set di test di regressione, per darti una certa sicurezza nel fare il refactoring in sicurezza.

questa è solo un'idea ...

+0

Interessante ... Cercherò questi strumenti. Grazie. La mia scelta personale è di sviluppare invece l'applicazione dal basso verso l'alto. Vengo dallo sfondo di applicazioni aziendali, quindi ho un maggiore rispetto per il livello di servizio e il modello di database, quindi mi piace affrontarlo per primo. Ma quello che dici- ha senso anche questo –

+0

questo potrebbe interessarti anche ... http://fitnesse.org/ FitNesse consente ai clienti, ai tester e ai programmatori di imparare cosa dovrebbe fare il loro software e di confrontare automaticamente quello a ciò che effettivamente fa. Confronta le aspettative dei clienti con i risultati effettivi. – zeroin23

+0

Questo è in genere il modo in cui viene eseguito BDD, puoi considerarlo come due cerchi concentrici, quello esterno è la funzione di alto livello, quella interna è l'implementazione di livello inferiore da cui dipende il livello elevato. Si inizia con l'alto livello utilizzando strumenti come fitnesse o cetriolo, quindi si definiscono ciascuno dei passaggi come un test eseguibile di alto livello utilizzando capibara o selenio, da lì si elabora il livello intermedio e infine il livello dati. Questo approccio ti dà la funzionalità fette verticali complete alla volta. –

3

saltare. Tutto andrà bene. Sono sicuro che hai una scadenza da rispettare. (/ sarcasmo)

Il mese prossimo, possiamo tornare indietro e ottimizzare le query in base al feedback degli utenti. E spezzare le cose che non sapevamo che non dovevamo interrompere.

Se pensate che il progetto durerà 2 settimane e non verrà mai più riaperto, i test automatici probabilmente sono una perdita di tempo. Altrimenti, se hai un interesse acquisito a "possedere" questo codice per alcuni mesi, ed è attivo, costruisci alcuni test. Usa il tuo giudizio su dove il maggior rischio è. Peggio ancora, se hai intenzione di stare con la compagnia per qualche anno, e avere altri compagni di squadra che si alternano a battere sui vari pezzi di un sistema, e potrebbe essere il tuo turno di nuovo tra un anno, costruisci alcuni test.

Non farlo, ma "incolla alcuni perni", in modo che se le cose iniziano a "muoversi", hai degli allarmi per attirare l'attenzione sulle cose.

La maggior parte dei miei test sono stati test di tipo JUnit o batch "diff" e uno strumento rudimentale di tipo screen raschietto che ho scritto alcuni anni fa (script di alcune regex + roba di tipo wget/curl). Ho sentito che Selenium dovrebbe essere un buon strumento per i test dell'interfaccia utente dell'applicazione Web, ma non l'ho provato. Qualcuno ha gli strumenti disponibili per le app della GUI locale ???

5

Mi sento come se confondessimo TDD con Unit Testing.

I test di unità sono test specifici che verificano unità di comportamento. Questi test sono spesso inclusi nella build di integrazione. S.Lott ha descritto alcuni candidati eccellenti solo per questi tipi di test.

TDD è per la progettazione. Trovo più spesso che i miei test che scrivo quando uso TDD verranno scartati o si evolveranno in un Test unitario. La ragione di questo è quando sto facendo TDD Sto testando il mio design mentre sto progettando la mia applicazione, classe, metodo, dominio, ecc ...

In risposta al tuo scenario sono d'accordo con ciò che S. Lott è implicito che ciò di cui hai bisogno è una suite di test unitari per testare comportamenti specifici nella tua applicazione.

1

In questi giorni non è necessario un codice scritto a mano per un'app CRUD oltre all'interfaccia utente, in quanto vi sono 101 framework che generano il database e il codice di accesso ai dati.

Quindi vorrei ridurre la quantità di codice scritto a mano e automatizzare il test dell'interfaccia utente. Quindi userei TDD degli strani elementi logici che devono essere scritti a mano.

3

TDDing una semplice applicazione CRUD è a mio avviso un po 'come la pratica di scale su una chitarra: potresti pensare che sia noioso e noioso solo scoprire quanto migliora il tuo modo di suonare. In termini di sviluppo, è probabile che si scriva codice meno abbinato, più verificabile. Inoltre, è più probabile che tu veda le cose dal punto di vista del consumatore del codice: lo utilizzerai effettivamente. Questo può avere un sacco di effetti collaterali interessanti come API più intuitive, una migliore segregazione delle preoccupazioni ecc. Garantito ci sono generatori di scaffold che possono fare CRUD di base per te e hanno un posto specialmente per la prototipazione, tuttavia sono solitamente legati ad un framework di sorta. Perché non concentrarsi prima sul dominio di base, rinviare le decisioni di Framework/UI/Database fino a quando non si ha un'idea migliore delle funzionalità di base necessarie - TDD può aiutarti a farlo anche tu. Nel tuo esempio: vuoi che i messaggi siano una coda o un albero gerarchico, ecc.? Vuoi che vengano caricati in tempo reale? Che dire di smistamento/ricerca? hai bisogno di supportare JSON o semplicemente html? è molto più facile vedere questo tipo di domande con BDD/TDD. Se stai facendo TDD potresti essere in grado di testare la tua logica di base senza nemmeno usare un framework (e aspettare un minuto per caricarlo/eseguirlo)