Concorso di unit test


12

I miei datori di lavoro organizzano una competizione mensile di test unitari. Un'intera giornata è dedicata alla scrittura di unit test - ovviamente facciamo più test durante il mese, ma questo è un giorno intero - e al "vincitore" della competizione viene assegnato un premio. Tuttavia, stiamo trovando difficile determinare chi è il vincitore.

Stavamo assegnando punti per ogni caso di test. Quindi se hai scritto un unit test come questo ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

ti verranno dati 100 punti. Ovviamente questo è un esempio semplicistico ma dimostra i problemi con l'assegnazione di "punti" a ciascun caso di test.

Siamo principalmente un negozio Java e Javascript. Quindi ho suggerito di contare il numero di rami di codice testati come metrica. Possiamo facilmente contare i rami testati tramite uno strumento di copertura del codice (come EclEmma). Tuttavia, non sono sicuro di come lo faremmo con i nostri test del selenio e ottenendo una copertura del codice sulle fonti Javascript (qualche idea?)

Qualcuno ha qualche suggerimento su come possiamo determinare meglio il vincitore di questa competizione?

modificare

So scrivere test unitari, so scrivere test unit efficaci, non ho bisogno di aiuto per determinare cosa testare. Non ho alcun controllo su questa competizione - la competizione continuerà. Quindi o aggiungo qualche input per renderlo migliore o continuo a giocare i test (sì, li gioco. Naturalmente li gioco. Ci sono premi da vincere)

modificare

Questa domanda qui non è ovviamente un duplicato, sebbene contenga informazioni utili su come trovare buoni casi di test, non fornisce metriche utili per valutare la concorrenza.


Non proprio. Me ne sono reso conto dall'inizio
Shaun,

2
Sembra che non ti rendi ancora conto del tutto. Qualsiasi misura di chi ha scritto i migliori casi di test sarà o completamente soggettiva o avrà questi problemi in una certa misura. Quale metrica funziona meglio dipenderà dai tuoi obiettivi per queste competizioni e da quanto sono maturi (cioè è improbabile che sfruttino il punteggio piuttosto che scrivere i migliori test che possono) i concorrenti.

Ancora una volta no. Mi sono reso conto che possono essere giocati. Non ho alcun controllo su questa competizione, ma mi è stato chiesto "come possiamo farlo meglio"
Shaun,

13
Sarebbe considerato un miglioramento non renderlo una competizione? Perché tutto deve essere una competizione? Perché non riesci a collaborare? Forse sbarazzarsi di alcuni dei tuoi test di unità più inutili e costruire una bella suite di utili test di fumo e regressione sarebbe utile.
Thomas Owens

1
Sono con Thomas ... il vincitore dovrebbe essere la base di codice / cliente perché la qualità del codice è migliorata. Imposta un obiettivo generale / di gruppo in base alla copertura del codice dei test unitari ... + 5% rispetto all'attuale o altro. ... e non giocare al sistema per i premi ... qualunque cosa sia successa a un lavoro ben fatto è la sua stessa ricompensa?
JeffC,

Risposte:


15

Qualcuno ha qualche suggerimento su come possiamo determinare meglio il vincitore di questa competizione?

L'unica cosa che ha senso per me è votare: ogni sviluppatore può assegnare alcuni punti al test di ogni altro sviluppatore (tranne il suo). Forse 3 punti per il test pensa che sia il più "efficace", 2 punti per il secondo e uno per il terzo. Il test con il maggior numero di punti vince. Può dare risultati migliori quando l'assegnazione del punto viene eseguita senza sapere in anticipo chi ha scritto il test specifico.

Come bonus, otterrai tutti i tuoi test peer review.


2
Questo era anche il mio pensiero. Non esiste altro modo per misurare il valore dei test.
Eric King,

2
Sì, "una buona prova" è una cosa così soggettiva che deve essere considerata a giudizio, da pari o da autorità rispettate. L'inseguimento delle metriche comporterà solo uno sforzo sprecato e poco valore reale. Potrebbe essere interessante avere più premi: test più fantasioso, un premio "test qualcosa precedentemente considerato non testabile", test delle migliori prestazioni, test più efficace, test più oscuro, test più intelligente, test più prezioso, test che molto probabilmente sarà apprezzato dagli utenti finali ...
giorno

6

Quindi se hai scritto un unit test come questo ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

ti verranno dati 100 punti.

Darei a questa persona 0 punti (anche se il test stava testando qualcosa di realmente rilevante), perché le asserzioni all'interno di un loop hanno poco senso e i test con più asserzioni (specialmente in una forma di loop o di una mappa) sono difficili da lavorare.

Il problema è essenzialmente quello di avere una metrica che non può [facilmente] essere truffata. Una metrica basata esclusivamente sul numero di asserzioni è esattamente la stessa del pagamento degli sviluppatori per LOC scritta. Come con pay-by-LOC che porta a un codice enorme e impossibile da mantenere, la tua politica aziendale effettiva porta a test inutili e probabilmente scritti male.

Se il numero di asserzioni è irrilevante, anche il numero di prove è irrilevante. Questo è anche il caso di molte metriche (comprese quelle combinate) che si potrebbero immaginare per questo tipo di situazioni.

Idealmente, applicheresti un approccio sistemico. In pratica, questo può difficilmente funzionare nella maggior parte delle società di sviluppo software. Quindi posso suggerire alcune altre cose:

  1. Usando le recensioni di coppia per i test e hai qualcosa di simile al numero di metriche WTF al minuto .

  2. Misura l'impatto di tali test nel tempo sul numero di bug . Ciò ha diversi vantaggi:

    • Sembra giusto,
    • In realtà può essere misurato se raccogli abbastanza dati sulle segnalazioni di bug e sul loro destino,
    • Ne vale davvero la pena!
  3. Utilizza la copertura delle filiali , ma combinala con altre metriche (oltre a una recensione). La copertura delle filiali ha i suoi vantaggi, ma testare il codice CRUD solo per ottenere un voto migliore non è il modo migliore per passare il tempo degli sviluppatori.

  4. Decidere tutti insieme quali sono le metriche che si desidera applicare per il momento (tali decisioni potrebbero non essere accolte favorevolmente o addirittura essere possibili in alcune società e team). Rivedi e modifica spesso le metriche, selezionando quelle che diventano più pertinenti e assicurati che tutti comprendano chiaramente cosa viene misurato e come.


1
+1 per zero punti. Altre obiezioni sarebbero AAA: organizzare, agire, affermare; Test con parametri; Nessuna copia del codice dell'implementazione ...
thepacker

5

Suppongo che il tuo datore di lavoro organizzi questa giornata di test unitari per darti incentivi per la ricerca di bug, per ottenere una maggiore copertura del codice e anche per finire per avere più test, utili per sempre.

Quindi, penso che avrebbe senso che il vincitore dovrebbe essere lo sviluppatore che trova il maggior numero di bug o lo sviluppatore i cui test ottengono il maggiore aumento della copertura del codice.

Un test ti farebbe guadagnare un punto se causasse l'apertura di una nuova voce nel tuo sistema di tracciamento di problemi / bug / difetti. Se una voce è già aperta per quel problema, non conta. Inoltre, come suggerito nei commenti, i bug nel tuo codice non contano; dovrebbero contare solo i bug nel codice di altre persone. Sfortunatamente, questo approccio non offre una gratificazione immediata perché potrebbero essere necessari alcuni giorni prima che tutti i test falliti vengano vagliati e aperti i problemi corrispondenti. Inoltre, questo potrebbe non funzionare sempre; man mano che il sistema matura, può iniziare a diventare estremamente raro scoprire bug aggiungendo test.

L'aumento della copertura del codice potrebbe fornire una misurazione più obiettiva del miglioramento rappresentato dai nuovi test. Innanzitutto, la copertura totale del codice dovrà essere registrata il giorno prima della competizione. Quindi, ogni sviluppatore dovrà mostrare in qualche modo l'aumento della copertura del codice che risulta dai soli test, senza tener conto dell'aumento della copertura del codice derivante dai test scritti da altri sviluppatori. Ciò significa che probabilmente avrai bisogno di un arbitro che andrà alla macchina di ogni sviluppatore e registrerà la copertura del nuovo codice prima che i test di chiunque siano stati eseguiti.

Per inciso, prendere in considerazione la copertura del codice offre una buona ricompensa alle persone che scrivono test reali, invece di fare cose sciocche come l'esempio che hai fornito nella domanda.


2
Sembra promettente ... ma poi il comportamento del "gioco del sistema" si trasforma in una bella collezione di bug conosciuti solo da te per essere "scoperti" nella prossima competizione di test ... dilbert.com/strip/1995-11 -13
martedì

3
Un'opzione è assegnare punti solo per i bug nel codice che qualcun altro ha scritto.
Cel Skeggs,


@ col6y hai ragione, anche questo è abbastanza importante. Sfortunatamente, ci sono ancora modi per attrezzare il sistema. Ad esempio, se il tuo codice invoca il mio codice per fare il suo lavoro, il mio codice potrebbe fare in modo che il tuo codice subisca un "incidente".
Mike Nakis,

3
Non sono d'accordo. I test unitari, quando sono stati appena scritti, non sono per prima cosa trovare bug , questo è un errore. Possono trovare regressioni settimane o mesi dopo che sono state scritte, ma molto probabilmente è troppo tardi per fornire metriche utili per la competizione. In genere scrivi un test unitario dopo che si è verificato un bug specifico per assicurarti di non ottenere lo stesso tipo di bug in futuro.
Doc Brown,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.