Costruire test di unità automatizzate per strumenti che non hanno un'implementazione xUnit

2

Preambolo

Sono stato morso dal bug del test automatico delle unità. Sento i benefici e la fiducia in un codice base che può fornire.

Anch'io sento di avere un'intuizione ragionevole riguardo a quali parti del codice meritano di essere sottoposte a test dell'unità. Codice che ha una logica, codice che potrebbe essere disordinato (perché ha a che fare con alcuni requisiti disordinati) che sei felice di aver incapsulato, che potrebbe avere qualche strana condizione marginale.

Contesto insolito

Nel mio posto di lavoro, sfruttiamo una serie di strumenti che sono abbastanza di nicchia. Per motivi di discussione, posso certamente vedere che questi strumenti offrono funzionalità ed efficienza che li rendono indispensabili per svolgere il loro particolare lavoro.

La sfida che ho è che ho sicuramente implementato la logica in questi strumenti che il mio istinto dice "questo dovrebbe essere coperto con un test unitario".

Ho testato questi bit di codice ...

  • In un modo usa e getta - prova diversi input per esercitare il codice fino a quando non funziona, questo ha il rovescio della medaglia di perdere sforzi quando si tratta di persone che mantengono il codice in futuro
  • In un modo meno gettabile ma manuale: scrivere i casi di test e i passaggi per attirare il codice per produrre output; con dati di test; in modo tale che i test di espulsione di cui sopra non vengano gettati via - questo mantiene l'investimento nel tempo, ma è lento e soggetto a persone che conoscono i test e li eseguono
  • In un modo un po 'più automatico - con script per eseguire il codice del codice; forse persino controllare l'output in modo graduale - è più piacevole da rieseguire, ma è lungi dall'utilizzare un framework maturo in modo coerente come quando si scrivono i test di stile xUnit

Mentre la progressione è piacevole, sento che mi manca l'esperienza xUnit di cui sono diventato fan.

Che tipo di lingue / piattaforme esattamente sto trattando qui?

  • Uno strumento ETL, simile a SSIS, chiamato Gestione dei dati RedPoint : non open source quindi descriverò, ha progetti che hanno strumenti, questi strumenti sono collegati da flussi di dati, e alcuni hanno una logica che desidero testare unitamente

  • Uno strumento di composizione, questo per chi non lo sapesse è un prodotto che prende un file di dati e genera un file di stampa. Immagina XML in, PDF out.

  • Funzioni di script DOS: prometto che questa è una vera caratteristica degli script DOS di buon livello, tutorial qui

  • (Aggiungerò questo alla lista, non strettamente su ciò di cui ho bisogno di aiuto, ma potrebbe essere più chiaro di quanto sopra se il mio set di strumenti è difficile da comprendere) Trasformazioni di COBOL, usando CopyBooks per specificare i formati degli input e output del file flat. Quando vengono compilati i risultati in un binario big-ball-of-mud anche se funzionalmente decomposto all'interno

The Actual Question

I test di stile xUnit sono fondamentalmente mirati alle lingue orientate agli oggetti?

    
posta Don Vince 05.03.2013 - 20:57
fonte

2 risposte

2

La distinzione non riguarda l'orientato agli oggetti o no, ma piuttosto il test delle singole funzioni ("white box testing") rispetto ai programmi completi ("black box testing"). E non si tratta di casi separati come un continuum in cui varie tecniche sono mescolate e abbinate.

Gli strumenti non sono monolitici. Un framework di test consiste di quattro cose:

  • Il test runner
  • Il reporter del risultato
  • La raccolta di asserzioni
  • (opzionalmente) Mock framework di oggetti

Questi componenti sono per lo più ortogonali e le loro implementazioni indipendenti possono essere combinati, sia i diversi tipi di componenti sia le molteplici implementazioni di ciascuno di essi.

Il test runner

Il componente che trova tutti i casi di test e li esegue. È possibile combinare più test runner semplicemente chiamando un corridore di test come test case da un altro corridore. Può essere semplice come un ciclo su una directory di script e questo è esattamente quello che spesso si utilizza come runner di primo livello quando si combinano test scritti in framework diversi.

Puoi trovare alcuni test runner universali in CTest o shUnit . Entrambi forniscono anche metodi per confrontare gli output nei file.

Il perl Test :: Harness può anche essere considerato corridore generale come esegue script nella directory. E perl è adatto anche per testare programmi esterni.

Il giornalista

Ogni framework di test unitario produce un elenco di test falliti. Se combini più framework, puoi semplicemente raccogliere tutti i singoli report o utilizzare qualcosa come subunità o Test::Harness "tocca" per fornire progressi e riepilogo uniformi.

Le asserzioni

Questo è il modo in cui test il codice testato produce risultati attesi ed è legato alla modalità di interfacciamento del codice.

  • Per le librerie in vari linguaggi di programmazione ci sono le asserzioni fornite dal rispettivo xUnit.
  • Per gli strumenti da riga di comando ci sono vari comparatori di file. CTest e shUnit ne hanno alcuni, ma sono per lo più facili da usare in homebrew se necessario.
  • Per gli strumenti da riga di comando interattivi c'è expect (o è Perl variante ).
  • Per le applicazioni della GUI c'è LDTP (progetto di test del desktop di Linux, ma ora anche le versioni di windows e macos)
  • Sono sicuro di aver visto qualcosa per le applicazioni web (significa nel browser, si testano i servizi attraverso la loro libreria client), ma non ricordo alcun nome. Ne troverai sicuramente alcuni con Google.

Strumento di simulazione

Si tratta di costruire l'ambiente di test senza impostare tutte le dipendenze reali. Per esempio. configurare un livello di accesso al database che restituisca un insieme specifico di risposte senza impostare il database effettivo e tali.

Non è possibile automatizzare tanto quanto è necessario fornire i dati che dovrebbe restituire. Spesso non è quello che vuoi comunque. Cioè è necessario testare l'applicazione con dati campione nel database effettivo o in un'altra fonte di dati e il test dei moduli a grana fine aggiuntivo spesso richiede molto lavoro con rendimenti decrescenti.

Non penso che molto possa essere generalizzato per questo. Per la maggior parte degli xUnits c'è qualcosa che genererà implementazioni fittizie per le interfacce, ma questo è tutto. Di quanto devi semplicemente considerare cosa richiede il componente da testare e qual è il modo più semplice per fornirlo localmente. Per qualcosa che comunica con alcuni servizi Web è possibile eseguire localmente un server http leggero. Per lo strumento di database che utilizza ODBC (o DBI o qualsiasi altra API universale), puoi testarlo su sqlite anche se normalmente utilizza un server grande, ecc. Per strumenti che leggono solo i file, ovviamente copi solo in un set di dati di prova adatto.

    
risposta data 07.03.2013 - 08:27
fonte
0

Non sono del tutto sicuro di quale tipo di strumenti stai parlando o di cosa li rende difficili da testare.

Ma potrebbe valere la pena dare un'occhiata a ApprovalTests ? Si tratta di un framework in più lingue (Java, C #, VB.Net, PHP, Ruby) che si trova sotto qualsiasi unità di test runner. Prende l'approccio di: invece di scrivere e testare e specificare il risultato atteso, scrivi il test, non specifica un risultato, esegui il test e poi ti mostra il risultato. Lo approvi. Da quel momento in poi, ogni volta che esegui il test, passerà se il risultato è invariato rispetto a quando lo hai approvato, e fallirà (presentandoti con una diff) se è cambiato.

Questo è ottimo per testare codice che restituisce più di semplici risultati scalari (raccolte, documenti XML, ecc.) E poiché viene eseguito in uno qualsiasi dei principali framework di test delle unità, non si perde nessuno dei propri strumenti per l'automazione , ecc.

    
risposta data 05.03.2013 - 21:18
fonte

Leggi altre domande sui tag