Utilizzo del codice legacy - introduzione di un'imbracatura di test di integrazione BDD esterna

5

Ecco lo scenario.

  • Esiste una grande applicazione sviluppata in modo organico e sviluppata in una lingua e in un modo che rende difficile la verifica. Funziona ma è difficile da mantenere.
  • Le specifiche sono lanose, quindi anche se il codice fosse accettabile, è difficile sapere cosa dovrebbero fare le cose senza farle.
  • Vuoi metterlo in un'imbracatura di prova in modo da poter iniziare a refactoring e creare test di unità adeguati.

In questi casi ha senso costruire un imbragatura 'test tutto' esterno o superficiale in modo da poter avviare un refactoring più aggressivo per consentire di scrivere test di unità adeguati. Questa sembra una pratica abbastanza consolidata di introdurre in modo incrementale test.

"La cosa principale che distingue il codice legacy dal codice non legacy è una mancanza test completi. "- Michael C. Feathers (Funzionante in modo efficace con il codice legacy)

La mia domanda è questa:

Ha senso creare una serie di test Behavior Driven a questo punto ed eseguirli tramite una sorta di clicker automatico dei pulsanti? Sto pensando a qualcosa (ma non limitato a) cetriolo o simile in cui i test leggibili dall'uomo corrispondono a codice / script eseguibili che dimostrano che il comportamento definito è stato rispettato.

Un chiaro vantaggio di questo è che una specifica di umano leggibile potrebbe essere sviluppata insieme ai test e che queste specifiche sono molto più facili da confermare come corrette e corrette con gli utenti / sviluppatori del sistema. Sono essenzialmente test di integrazione ma svolgono la funzione raccomandata da Feathers.

eta: Non sto chiedendo un suggerimento specifico per uno strumento, lo strumento attuale è irrilevante (anche se sarebbe utile sapere se effettivamente esiste). Sto cercando un controllo di integrità e raccomandazioni sui test di integrazione BDD esterni.

    
posta tom 05.01.2015 - 12:11
fonte

3 risposte

7

È perfettamente possibile farlo. Ho scritto un blog con alcune linee guida , ma questi aggiuntivi potrebbe aiutarti anche tu:

  • Pensa alle capacità del sistema. Ad esempio, un sistema di contabilità potrebbe essere in grado di leggere i feed bancari, aumentare le fatture, inviare via e-mail tali fatture, ecc.

  • Raggruppa gli scenari in termini di capacità. Guarda che tipo di contesti (i dati) producono che tipo di risultati (i thens). Avere alcune conversazioni con gli uomini d'affari su questi, e prendere la loro lingua il più lontano possibile. Le funzionalità stesse guideranno ciò che scrivi per gli eventi (i whens).

    Ad esempio, potresti trovare un paio di scenari per l'aumento delle fatture dove si dice qualcosa del tipo:

    Given an organisation to bill is outside the US
    When we send the invoice
    Then international bank details should be included.

    Given an organisation to bill is within the US
    When we send the invoice
    Then it should include only US bank details.

    Saranno quindi collegati all'automazione che esegue i passaggi più dettagliati che effettivamente creano organizzazioni con indirizzi diversi in paesi diversi, inviano le fatture e verificano che tali fatture siano state inviate con i dati bancari corretti. Ci saranno molti più passaggi di automazione rispetto a quelli di livello superiore. Questo è comunemente definito linguaggio dichiarativo vs imperativo e ti aiuterà a capire quali sono gli scenari più importanti da coprire e che sono funzionalmente equivalenti.

    Si noti che la differenza tra gli scenari viene definita in modo abbastanza pulito qui, cosa che non sarebbe se esistessero più passaggi dell'interfaccia utente che nascondono tale differenza. La differenza tra gli scenari è ciò che illustra il comportamento .

  • Probabilmente troverai bug. Spetta a te se vuoi scrivere scenari su ciò che il sistema dovrebbe fare. È molto probabile che a questo punto ci siano alcuni workaround umani, quindi non mi preoccuperei troppo di questo comportamento. Se l'applicazione è in natura e produce valore, va bene. Assicurati di ottenere scenari intorno alle funzionalità principali scritte per prime.

  • Ogni volta che devi correggere un bug, scrivi alcuni test unitari . Questo ti costringerà a riprogettare il tuo codice. I bug di regressione sono di solito causati da un design scarso, e l'aggiunta di altri scenari renderà il codice più difficile da modificare invece di darvi più fiducia in esso. Questo è ciò a cui Michael Feathers si riferisce principalmente qui. Vedi anche la piramide di test . Man mano che il sistema viene refactored, il numero di test unitari e test di integrazione dovrebbe superare rapidamente quelli del livello di interfaccia utente.

  • Puoi utilizzare le diverse funzionalità del sistema per guidarti nel trovare le giunture di cui Michael parla nel suo libro, che ti aiuterà a refactoring.

  • Si noti che non uso la parola test molto spesso. Gli uomini d'affari tendono a parlare più comodamente del comportamento del sistema quando si parla di esempi o scenari in cui le cose accadono rispetto a quando si parla di test. Questo rimanda alle origini di BDD .

Buona fortuna!

    
risposta data 05.01.2015 - 23:46
fonte
1

BDD è sicuramente possibile nel sistema Legacy. Ho partecipato personalmente all'elevazione di molteplici progetti Legacy con anni di storia. Uno degli aspetti chiave del BDD è quello di arricchire la comprensione del team di ciò che è effettivamente necessario e quindi fornire un percorso sostenibile per apportare cambiamenti incrementali verso di esso e da esso. Nella mia esperienza, l'aspetto comune del sistema Legacy è che una grande parte di esso è già stata eseguita con una grande parte di esso che non cambia mai più. Tenendo questo a mente, i tentativi di adeguare la BDD ai casi d'uso che sono già stati consegnati porteranno inevitabilmente a sprecare: finirai per discutere di un enorme elenco di cose che la maggior parte delle quali non cambieranno mai e testeranno un enorme elenco di cose la maggior parte delle quali non si romperà mai.

Come ha detto Liz (lunivoro), l'aspetto chiave nell'approcciare tali progetti è identificare le capacità del progetto. Per far avanzare il progetto Legacy è necessario chiudere gli occhi per un momento sulle cose che sono state fatte e guardare le cose che cambieranno. Identificare le priorità aziendali chiave per i prossimi due mesi. Ciò ti aiuterà a capire quali nuove funzionalità dovranno essere aggiunte e quali funzionalità esistenti dovranno essere modificate. Trovo pratiche come Impact Mapping che funzionano molto bene qui. Avere conversazioni su queste funzionalità e utilizzare i risultati di queste conversazioni per fare BDD. A questo proposito, BDD su progetti Brownfield non è molto diverso da BDD su quelli di Greenfield.

La più grande differenza è il modo in cui tecnicamente la affrontate: i progetti legacy avranno naturalmente molto più end-to-end semplicemente per la loro natura, va bene. La pratica chiave qui è di non mantenere questi test end-to-end per troppo tempo. Non appena hai scritto un test end-to-end, l'orologio dovrebbe iniziare a spuntare affinché tu possa refactoring il codice sottostante nel tentativo di renderlo unit-testabile. Chiamo questo processo di migrazione a livello di test e ne ho scritto in modo più dettagliato ieri:)

Oltre a coprire le modifiche e le nuove funzionalità, incontrerai sicuramente dei bug. È importante qui capire che nella maggior parte dei casi sul codebase non testato non sarai in grado di prevederli. Quindi, invece di provare a predire i bug, prova a prepararli - stai attento con le aree critiche. Discutere e automatizzare il viaggio interrotto non appena viene rilevato un difetto, ma non prima. Altrimenti è molto possibile spendere troppi soldi e tempo per testare cose che non si romperanno mai, sprecando efficacemente risorse invece di fornire valore.

Spero che questo aiuti.

    
risposta data 06.01.2015 - 18:38
fonte
0

Does it make sense to build a suite of Behaviour Driven tests at this point and execute them via some kind of automated button clicker?

Almeno sembra ragionevole. Quello che stai suggerendo può essere implementato da qualsiasi "GUI robot" con un supporto per i test basati sui dati (non ho intenzione di suggerirti uno strumento, guarda qui per iniziare). Se il frontend per la creazione dei test non è abbastanza "stile BDD", penso che la creazione di un'interfaccia tra cetriolo e il robot della GUI non dovrebbe essere troppo difficile.

Attenzione però: la creazione di tali test richiederà sicuramente un certo sforzo, specialmente quando si sta tentando di creare una "prova tutto". Devi valutare da solo se il beneficio che ottieni da questo supera lo sforzo. Inoltre, la mia esperienza con gli strumenti di automazione della GUI è che i test creati con loro tendono a diventare fragili (ma YMMV).

    
risposta data 05.01.2015 - 13:34
fonte

Leggi altre domande sui tag