Qual è il punto di esecuzione dei test unitari su un server CI?

94

Perché dovresti eseguire i test unitari su un server CI?

Sicuramente, quando qualcosa si impegna a padroneggiare, uno sviluppatore ha già eseguito tutti i test unitari e ha riparato eventuali errori che si sarebbero verificati con il loro nuovo codice. Non è questo il punto dei test unitari? Altrimenti hanno appena eseguito il codice errato.

    
posta Steve 27.01.2016 - 14:21
fonte

9 risposte

219

Surely, by the time something gets committed to master, a developer has already run all the unit tests before and fixed any errors that might've occurred with their new code.

Oppure no. Ci possono essere molte ragioni per cui questo può accadere:

  • Lo sviluppatore non ha la disciplina per farlo
  • Hanno dimenticato
  • Non hanno commesso tutto e hanno spinto un set di commit incompleto (grazie Matthieu M.
  • Hanno eseguito solo alcuni test, ma non l'intera suite (grazie nhgrif )
  • Hanno testato sul loro ramo prima della fusione (grazie nhgrif * 2)

Ma il vero punto è eseguire i test su una macchina che non è la macchina dello sviluppatore. Uno configurato in modo diverso.

Questo aiuta a individuare i problemi in cui i test e / o il codice dipendono da qualcosa di specifico per una casella sviluppatore (configurazione, dati, fuso orario, impostazioni internazionali, qualunque sia).

Altre buone ragioni per le build CI per eseguire test:

  • Test su piattaforme diverse dalle principali piattaforme di sviluppo, che possono essere difficili da fare per uno sviluppatore. (Grazie TZHX )
  • Accettazione / Integrazione / End-to-end / I test realmente lunghi possono essere eseguiti sul server CI che normalmente non verrebbero eseguiti su una casella di sviluppo. (grazie Ixrec )
  • Uno sviluppatore può fare un piccolo cambiamento prima di premere / impegnare (pensando che questo sia un cambiamento sicuro e quindi non esegua i test). (grazie Ixrec * 2)
  • La configurazione del server CI di solito non include tutti gli strumenti di sviluppo e la configurazione e quindi è più vicina al sistema di produzione
  • I sistemi CI costruiscono il progetto da zero ogni volta, il che significa che le build sono ripetibili
  • Una modifica della libreria potrebbe causare problemi a valle - un server CI può essere configurato per creare tutti basi di codice dipendenti, non solo la libreria
risposta data 27.01.2016 - 14:24
fonte
73

Come sviluppatore che non esegue tutti i test di integrazione e unità prima di eseguire il commit del controllo del codice sorgente, offrirò la mia difesa qui.

Dovrei creare, testare e verificare che un'applicazione venga eseguita correttamente:

  • Microsoft Windows XP e Vista con il compilatore di Visual Studio 2008
  • Microsoft Windows 7 con il compilatore Visual Studio 2010.
    • Oh, e MSI costruisce per ognuno di questi.
  • RHEL 5 e 6 con rispettivamente 4.1 e 4.4 (analogamente CentOS)
    • 7 presto. Woop-de-woop.
  • Fedora Workstation con GCC per le ultime tre versioni recenti.
  • Debian (e derivati come Ubuntu) per le ultime tre versioni recenti.
  • Mac OSX nelle ultime tre versioni recenti.
    • E i pacchetti (rpm, dmg, ecc.)

Aggiungi il Fortran (con entrambi i compilatori Intel e GNU), Python (ed è varie versioni a seconda del sistema operativo) e componenti script bash / bat e, beh, penso che tu possa vedere le cose a spirale fuori

Quindi sono sedici macchine che dovrei avere, solo per eseguire alcuni test un paio di volte al giorno. Sarebbe quasi un lavoro a tempo pieno solo per gestire l'infrastruttura per quello. Penso che quasi tutti sarebbero d'accordo che è irragionevole, soprattutto moltiplicandolo per il numero di persone nel progetto. Quindi lasciamo che i nostri server CI facciano il loro lavoro.

I test unitari non ti impediscono di scrivere codice non funzionante, ti dicono se conosci di aver violato qualcosa. Le persone possono dire "i test unitari devono essere veloci" e continuare su principi e schemi di progettazione e metodologie, ma in realtà a volte è meglio lasciare che i computer che abbiamo progettato per compiti ripetitivi e monotoni li facciano e vengano coinvolti solo se diteci che hanno trovato qualcosa.

    
risposta data 27.01.2016 - 14:58
fonte
22

Penseresti che non lo farebbe tu - ma gli sviluppatori sono umani e a volte dimenticano.

Inoltre, gli sviluppatori spesso non riescono a estrarre il codice più recente. I loro test più recenti potrebbero andare bene, quindi al momento del check-in, qualcun altro si impegna a cambiare.

I tuoi test possono anche fare affidamento su una risorsa locale (non selezionata). Qualcosa che i tuoi test di unità locali non avrebbero rilevato.

Se ritieni che tutto ciò che è sopra è fantasioso, c'è un livello sopra l'IC (almeno su TFS) chiamato Gated dove le build che hanno test falliti sono accantonate e non sono impegnate nella base del codice .

    
risposta data 27.01.2016 - 14:23
fonte
22

A parte l'eccellente risposta Odessa:

  • Esegui il test del codice dal repository . Potrebbe funzionare sulla tua macchina con i tuoi file ... che hai dimenticato di commettere. Può dipendere da una nuova tabella che non ha lo script di creazione (ad esempio in liquibase), alcuni dati di configurazione o file di proprietà.
  • Evita i problemi di integrazione del codice. Uno sviluppatore scarica l'ultima versione, crea test di unità e integrazione, aggiunge codice, passa tutti i test nella sua macchina, commette e spinge. Un altro sviluppatore ha appena fatto lo stesso. Entrambe le modifiche sono corrette, ma quando unite causa un bug. Questo potrebbe essere la fusione del repository o semplicemente che non viene rilevato come conflitto. Per esempio. Dev 1 cancella il file che non è stato utilizzato affatto. Dev 2 codici contro questo file e test senza modifiche di Dev 1.
  • Sviluppa uno script da distribuire automaticamente dal repository. Avere un edificio e una distribuzione universali risolve un sacco di problemi. Alcuni sviluppatori potrebbero aver aggiunto un'opzione di compilazione o di compilazione non condivisa da tutti. Ciò non solo ti fa risparmiare tempo, ma soprattutto, rende la distribuzione sicura e prevedibile. Inoltre, puoi tornare nel tuo repository alla versione 2.3.1 e distribuire questa versione con uno script che funziona con questa versione. Include oggetti di database come viste, stored procedure, viste e trigger che dovrebbero essere versionati. (Oppure non sarai in grado di tornare a una versione praticabile).
  • Altri test : come integrazione, prestazioni e test end-to-end. Questo può essere lento e potrebbe includere strumenti di test come il selenio. Potrebbe essere necessario un set completo di dati con un vero database invece di oggetti mock o HSQL.

Una volta ho lavorato in un'azienda che aveva molti bug sulla distribuzione a causa del processo di fusione e distribuzione. Ciò è stato causato da una strana struttura propiziaria che ha reso difficili i test e l'IC. Non è stata una felice esperienza scoprire che il codice che ha funzionato perfettamente sullo sviluppo non è arrivato alla produzione.

    
risposta data 27.01.2016 - 16:13
fonte
14

by the time something gets committed to master

Normalmente ho impostato il mio CI per l'esecuzione su ogni singolo commit. I rami non vengono uniti in master finché il ramo non è stato testato. Se ti stai affidando all'esecuzione di test su master, allora viene aperta una finestra in cui la build deve essere interrotta.

L'esecuzione dei test su una macchina della CI riguarda risultati riproducibili. Poiché il server CI ha un ambiente pulito noto estratto dal tuo VCS, sai che i risultati del test sono corretti. Quando esegui localmente, potresti dimenticarti di eseguire il commit del codice necessario per il loro passaggio o di avere codice non eseguito che li faccia passare quando dovrebbero fallire.

Può anche far risparmiare tempo agli sviluppatori eseguendo suite diverse in parallelo, specialmente se alcuni sono test lenti e multi-minuto che non saranno probabilmente eseguiti in locale dopo ogni modifica.

Al mio attuale lavoro, la nostra implementazione di produzione è controllata su CI passando tutti i test. Gli script di distribuzione impediranno la distribuzione a meno che non stiano passando. Ciò rende impossibile dimenticarsi accidentalmente di eseguirli.

Anche l'essere parte del flusso di lavoro fa parte degli sviluppatori. Come sviluppatore, di solito esegui un linter, un analizzatore statico, un test unitario, una copertura del codice e un test di integrazione per ogni singola modifica? CI può, in modo completamente automatico e senza bisogno di pensarci, riducendo la fatica decisionale.

    
risposta data 27.01.2016 - 14:29
fonte
4

Quando qualcosa si impegna a padroneggiare, uno sviluppatore dovrebbe avere già eseguito tutti i test unitari ... ma se non lo fossero? Se non esegui i test unitari sul server CI, non lo saprai fino a quando qualcun altro non apporterà le modifiche alla loro macchina e scoprirà che i test sono appena terminati.

Inoltre, lo sviluppatore potrebbe aver commesso un errore e fare riferimento a una risorsa locale specifica per il proprio computer. Quando eseguono il check-in del codice e l'esecuzione del CI fallisce, il problema viene identificato immediatamente e può essere corretto.

    
risposta data 27.01.2016 - 14:24
fonte
3

Supponendo (contrariamente ad altre risposte) che gli sviluppatori siano abbastanza disciplinati e facciano dei test unitari prima di impegnarsi, ci possono essere diversi motivi:

  • i test di unità in esecuzione possono richiedere molto tempo per alcune impostazioni speciali. Ad esempio, eseguire test di unità con il controllo della memoria (come valgrind) può richiedere molto più tempo. Sebbene tutti i test unitari stiano passando, il controllo della memoria può fallire.
  • il risultato non è così importante per alcune impostazioni speciali - ad esempio, eseguire test di unità per verificare la copertura del codice richiede speciali flag di compilazione. Per gli sviluppatori normali, la copertura del codice non è così importante - è più per le persone che si prendono cura del fatto che il codice mantiene una certa qualità, come i lead del team.
risposta data 27.01.2016 - 14:33
fonte
3

È possibile immaginare casi in cui la modifica A non interrompe il test e il cambiamento di B non interrompe il test, ma A e B insieme fanno. Se A e B sono realizzati da diversi sviluppatori, solo il server CI rileverà il nuovo bug. A e B possono anche essere due parti della stessa frase più lunga.

Immagina un treno guidato dalle due locomotive A e B. Forse uno è più che sufficiente e questa è la soluzione da applicare. Tuttavia se vengono applicate le due "correzioni" rimuovendole entrambe, il treno non si muoverà.

Inoltre, non tutti gli sviluppatori eseguono tutti i test di unità, mentre la maggior parte dei buoni sviluppatori lo fanno.

    
risposta data 28.01.2016 - 09:11
fonte
2

Facciamo una domanda equivalente:

Why would you build the code on a CI server?

Surely, by the time something gets committed to master, a developer has already built the code before and fixed any errors that might've occurred with their new code. Isn't that the point of building code? Otherwise they've just committed broken code.

Ci sono diversi motivi per fare l'IC, ma il punto principale dell'IC è quello di farsi un'idea di quale sia lo stato del codice nel tempo. Il vantaggio principale (tra i molti) di questo, è che possiamo scoprire quando la costruzione si rompe, capire cosa lo ha rotto e poi ripararlo.

Se il codice non viene mai interrotto, perché usiamo anche CI? Per fornire build per i test, le build notturne sarebbero sufficienti.

    
risposta data 29.01.2016 - 13:59
fonte