TDD - Outside In vs Inside Out

50

Qual è la differenza tra la creazione di un'applicazione Outside In rispetto alla sua costruzione Inside Out utilizzando TDD?

Questi sono i libri che ho letto su TDD e test delle unità:
Sviluppo basato su test: per esempio
Sviluppo basato sui test: una guida pratica: una guida pratica
Soluzioni real-world per lo sviluppo di framework e applicazioni PHP di alta qualità
Sviluppo basato su test in Microsoft .NET
xTest di test di unità: refactoring Test Code
The Art of Unit Test: con esempi in .Net
< a href="http://rads.stackoverflow.com/amzn/click/0321503627"> Crescita del software orientato agli oggetti, guidato dai test --- > Questo è stato davvero difficile da capire poiché JAVA non è t la mia lingua principale:)

Quasi tutti hanno spiegato le basi del TDD e il test delle unità in generale, ma con una piccola menzione dei diversi modi in cui l'applicazione può essere costruita.

Un'altra cosa che ho notato è che la maggior parte di questi libri (se non tutti) ignora la fase di progettazione durante la scrittura dell'applicazione. Si concentrano maggiormente sulla scrittura dei casi di test in modo rapido e lasciando che il progetto emerga da solo.

Tuttavia, mi sono imbattuto in un paragrafo in xUnit Test Patterns che ha discusso i modi in cui le persone si avvicinano al TDD. Ci sono 2 scuole là fuori Outside In vs Inside Out .

Purtroppo il libro non approfondisce questo punto. Vorrei sapere qual è la principale differenza tra questi 2 casi.
Quando dovrei usare ognuno di loro?
Per un principiante TDD quale è più facile da afferrare?
Quali sono gli svantaggi di ciascun metodo?
Esistono materiali che discutono specificamente di questo argomento?

    
posta Songo 27.09.2012 - 13:05
fonte

4 risposte

42

Inside-Out e Outside-In sono termini piuttosto rari, più spesso ho sentito / letto su Scuola classica e scuola di Londra .

  • Inside-Out (scuola classica, bottom-up ): si inizia a livello di componente / classe (all'interno) e si aggiungono test ai requisiti. Man mano che il codice si evolve (a causa dei refactoring), appaiono nuovi collaboratori, interazioni e altri componenti. TDD guida completamente il design.

  • Outside-In (scuola di Londra, top-down o "mockist TDD" conosci delle interazioni e dei collaboratori in anticipo (specialmente quelli ai massimi livelli) e parti da lì (livello superiore), prendendo in giro le dipendenze necessarie. Con ogni componente finito, si passa ai collaboratori precedentemente derisi e si inizia nuovamente con TDD, creando implementazioni reali (che, anche se utilizzate, non erano necessarie prima grazie alle astrazioni ). Nota che l'approccio outside-in si sposa bene con il principio YAGNI .

Nessuno dei due approcci è l'unico ; entrambi hanno il loro posto a seconda di quello che fai. In grandi soluzioni aziendali, dove parti del design provengono da architetti (o esistono in anticipo) si potrebbe iniziare con l'approccio "stile londinese". D'altra parte, quando affronti una situazione in cui non sei sicuro di come dovrebbe apparire il tuo codice (o di come dovrebbe adattarsi ad altre parti del tuo sistema), potrebbe essere più facile iniziare con un componente di fascia bassa e lasciarlo evolvi man mano che vengono introdotti più test, refactoring e requisiti.

Qualsiasi cosa tu usi, il più delle volte è situazionale.

Per ulteriori informazioni, post di gruppo di Google con una discussione piuttosto interessante su come questa distinzione (potrebbe avere) originata e sul perché Londra potrebbe non essere il nome più appropriato.

    
risposta data 27.09.2012 - 13:48
fonte
15

Risposta breve: come al solito dipenderà dalle preferenze di codifica e dall'approccio di squadra.

La codifica

Inside out è eccezionale perché hai sempre qualcosa in gioco. Il rovescio della medaglia è che non necessariamente ti aiuta ad arrivare in un posto radicalmente diverso. È più difficile tracciare un percorso in questo modo. Allo stesso modo, scrivere codice all'esterno di non ha necessariamente il vantaggio di uno sviluppo iterativo rapido, e non necessariamente vede tutte le opportunità e gli schemi che possono sorgere dal profondo della struttura del codice.

Sono arrivato a credere che entrambi gli stili di sviluppo siano importanti , e che sia di fatto utile avere un mix di stili in una squadra. L'idea è che l'esterno è ottimo per creare elementi costitutivi, e l'esterno nel pensiero fornisce struttura e direzione della forma.

Parte del mio ragionamento proviene da una scuola di pensiero molto popolare che attualmente promuove lo sviluppo iterativo, che è spesso sinonimo di sviluppo senza precedenti. Io credo che lo sviluppo iterativo sia ottimo quando non hai molto da fare. Ma penso che il pensiero generale, al contrario di un processo puramente iterativo, sia inestimabile per certi tipi di innovazione e per raggiungere un posto meno ovvio. Gestito correttamente, dentro e fuori insieme possono essere una combinazione molto efficace.

    
risposta data 27.09.2012 - 13:35
fonte
8

Devi aggiungere Agile Prinicples, Patterns and Practices in C # a quella lista. Non so perché abbia virato "in C #" alla fine. I libri non sono affatto la lingua e l'unica ragione per cui non ha ottenuto 5 stelle su Amazon è da parte di persone che sono state deluse dal C # -nessione dei suoi esempi.

L'autore sostiene che, quando possibile, dovresti provare a scrivere codice al di fuori e fare molto affidamento sul design evolutivo, e sono d'accordo con la sua affermazione. Il suo ragionamento è che mentre aggiungiamo funzionalità, il nostro design si evolverà sempre. Se iniziamo con componenti di basso livello man mano che le funzionalità vengono aggiunte, ci rendiamo conto che quei componenti non stanno facendo ciò che vorremmo che facessero, o che le cose dovessero essere spostate. Questo potrebbe diventare piuttosto costoso, soprattutto se ogni volta che trasferisci le funzionalità da una classe all'altra, devi fare la stessa mossa in tutti i progetti di test unitari.

D'altra parte, se si determina cosa deve fare la propria applicazione in primo luogo, si codifica per l'interfaccia esterna. A mano a mano che le funzioni vengono aggiunte e il codice in prova aumenta di dimensioni, puoi ridimensionare l'applicazione in più classi, ma mentre questo sforzo di refactoring procede, i test di unità originali che hai scritto rimangono validi. Quindi inizi completamente all'esterno e continui a rifattare in classi sempre più di basso livello, aggiungendo ulteriori test unitari a quelle interne, ma raramente dovrai spostarti e riscrivere i test delle unità.

Tuttavia, se si identifica uno specifico sottosistema di basso livello di cui avrà bisogno l'applicazione (e forse la propria azienda ha già bisogno di tale sottosistema in altre applicazioni), questo sarebbe il momento di iniziare con un building block di basso livello prima e poi costruisci l'app.

    
risposta data 27.09.2012 - 16:18
fonte
7

Per come la vedo io, il concetto di sviluppo di Outside-in si estende davvero su 2 livelli. Gerard Meszaros brevemente descrive come "outside-in design " e "all'esterno -in / inside-out coding ".

  • Il primo livello è un livello organizzativo e di processo. Il design esterno è inteso come contrario a quello dall'alto verso il basso (cascata / taylorist) e dal basso verso l'alto. Con un approccio esterno, ci concentriamo sulla prospettiva dell'utente finale. Iniziamo con i test di storia, ATDD o BDD e andiamo "verso l'interno" deducendo test tecnici e codice. Quindi la progettazione esterna è in genere ciò che si farebbe in un contesto Agile. Dan North ha un ottimo talk sugli approcci BDD, top-down, bottom-up e outside-in.

  • Il secondo livello è tecnico e ha a che fare con i livelli applicativi. La codifica di Outside-in significa fondamentalmente l'avvio dall'interfaccia utente e l'inoltro verso lo strato centrale (di solito il livello business / dominio). È inteso come opposto alla codifica inside-out che inizia dal livello centrale e codifica per ultimi gli strati esterni.

Quindi potresti avere design esterno con codifica esterna o codifica interna.

Dove non sono d'accordo con Meszaros è quando associa la codifica interna con i test di integrazione, sostenendo che in un contesto "fuori-dentro" non testiamo realmente il software esterno in isolamento del software interno ". Ma credo che niente ti impedisca di farlo. Puoi scegliere perfettamente di testare gli oggetti del livello esterno prendendo in giro gli oggetti del livello interno, anche se il codice di produzione di quelli esistenti esiste già. Devi semplicemente aggiungere interfacce e mock agli oggetti concreti esistenti invece di scrivere le interfacce, prenderle in giro e poi creare le implementazioni in un secondo momento, come faresti con la codifica esterna.

In altre parole, il TDD stile mockista o classicista è IMO una preoccupazione ortogonale per la codifica di fuori-dentro / dentro. Puoi usare perfettamente uno stile mockista insieme ad un approccio al di fuori. La ragione di questo è che lo stile mockista / classicista riguarda le dipendenze del codice mentre la codifica di fuori-dentro / dentro-fuori riguarda i livelli applicativi.

Un'altra cosa importante è che le dipendenze non sono solo trasversali, ma esistono anche tra oggetti nello stesso livello. Ad esempio, potresti voler iniziare con un oggetto nel tuo livello aziendale centrale (approccio inside-out) e usare i mock per isolare il tuo oggetto da altri oggetti del livello aziendale con cui parla. Questo accade molto con IoC: le astrazioni da cui dipende l'oggetto sono spesso dichiarate nello stesso livello, ma le implementazioni concrete si trovano in un livello diverso.

Robert "Uncle Bob" Martin menziona brevemente la codifica interna e come non sia necessariamente in conflitto con un'architettura disaccoppiata nel suo post " Pulisci architettura ".

    
risposta data 28.09.2012 - 01:04
fonte

Leggi altre domande sui tag