Devo avere test unitari per difetti noti?


37

Se il mio codice contiene un difetto noto che dovrebbe essere corretto, ma non lo è ancora, e non sarà risolto per la versione corrente e potrebbe non essere risolto in un futuro prevedibile, dovrebbe esserci un test unitario fallito per quel bug in la suite di test? Se aggiungo il test unitario, fallirà (ovviamente) e abituarsi ad avere dei test falliti sembra una cattiva idea. D'altra parte, se si tratta di un difetto noto e si riscontra un caso di fallimento noto, sembra strano tenerlo fuori dalla suite di test, come dovrebbe essere riparato ad un certo punto e il test è già disponibile.


6
Non penso così moscerino, chiedo in particolare di unit test
Martijn

3
i test per difetti noti sono noti come test di regressione , questi non hanno nulla a che fare con i test unitari ... per essere precisi, quest'ultimo dipende dall'opinione dello sviluppatore - la tua domanda non è forse un duplicato dopo tutto, ma piuttosto un sondaggio per le opinioni. È particolarmente evidente che la risposta che hai accettato non usa affatto il termine "test unitari", ma piuttosto ragionevolmente chiama questi "test falliti noti" in modo diverso
moscerino

3
Grazie Michael, questo aiuta su come contrassegnare tali test in JUnit, ma non proprio sulla pratica dei test. moscerino, ancora non capisco come vedi un test unitario fallito come test di regressione. Anche i tuoi commenti ottengono un'atmosfera passivamente / aggressiva distintamente ostile. Se pensi che dovrei porre domande in modo diverso, per favore dillo, perché non posso rispondere alle tue preoccupazioni se le pronunci in questo modo.
Martijn,

3
@gnat: onestamente, IMHO non importa se chiamiamo i test qui "test" o "test di regressione" - anche la domanda che hai collegato ha un focus diverso, e le risposte lì non si applicano qui.
Doc Brown,

Risposte:


51

La risposta è sì, dovresti scriverli e dovresti eseguirli.

Il tuo framework di test ha bisogno di una categoria di "test falliti noti" e dovresti contrassegnarli come rientranti in quella categoria. Come lo fai dipende dal framework.

Curiosamente, un test fallito che passa all'improvviso può essere altrettanto interessante di un test che passa inaspettatamente.


7
Un esempio della funzionalità di cui sopra nel framework unittest di Python: docs.python.org/3.3/library/…
Jace Browning

5

Penso che dovresti avere un test unitario con il comportamento attuale e nei commenti, aggiungere il test giusto e il comportamento giusto. Esempio:

@Test
public void test() {
  // this is wrong, it should be fixed some time
  Assert.assertEquals(2, new Calculator().plus(2,2));
  // this is the expected behaviour, replace the above test when the fix is available
  // Assert.assertEquals(4, new Calculator().plus(2, 2));
}

In questo modo, quando la correzione è disponibile, la compilazione fallirà, notando il test fallito. Quando guarderai il test, saprai che hai cambiato il comportamento e il test deve essere aggiornato.

EDIT: Come ha detto Captain Man, in grandi progetti, questo non verrà risolto in qualsiasi momento presto ma per motivi di documentazione, la risposta originale è meglio di niente.

Un modo migliore per farlo è duplicare il test corrente, facendo affermare al clone la cosa giusta e @Ignorecon un messaggio, ad es.

@Test
public void test() {
  Assert.assertEquals(2, new Calculator().plus(2,2));
}

@Ignore("fix me, Calculator is giving the wrong result, see ticket BUG-12345 and delete #test() when fixed")
@Test
public void fixMe() {
  Assert.assertEquals(4, new Calculator().plus(2, 2));
}

Questo viene fornito con la convenzione del tuo team per ridurre il numero di @Ignored test. Allo stesso modo in cui si farebbe con l'introduzione o la modifica del test per riflettere il bug, tranne per il fatto che non si fallisce la compilazione se questo è fondamentale per il proprio team, come OP ha detto che il bugfix non verrà incluso nella versione corrente .


1
Questo è un cattivo consiglio. Nessuno tenterà mai di risolverlo. Le persone apriranno vecchi test unitari solo se ci sono problemi di compilazione o fallimenti dei test.
Capitano Man

@CaptainMan Sono d'accordo, ho aggiornato la mia risposta per fornire un modo migliore al team di sviluppo di essere a conoscenza di un bug senza fallire la compilazione. Il tuo downvote era giustificato per la risposta originale che ho pubblicato 3 anni fa, credo che la risposta attuale sia più appropriata. Lo faresti in un altro modo?
Silviu Burcea

Questo è quasi esattamente quello che faccio nelle rare occasioni in cui non riesco a risolvere il bug ora per qualche motivo. Mi piacerebbe sapere come gestisci la situazione @CaptainMan
RubberDuck

@RubberDuck Non c'è davvero nessuna situazione ideale qui (oltre a correggere il bug ora haha). Per me, almeno vedere nei risultati del test "10 passati, 0 falliti, 1 saltato" è almeno un'indicazione che qualcosa è sospetto per le persone che non lo conoscono. Preferisco l' @Ignoreapproccio. La ragione per cui usare solo un commento non mi sembra una buona idea è perché non penso che le persone aprano spesso test unitari per controllarli (a meno che non stiano fallendo, o (si spera) quando si chiedono perché qualcosa viene ignorato ).
Captain Man,

@RubberDuck Non c'è davvero nessuna situazione ideale qui (oltre a correggere il bug ora haha). Per me, almeno vedere nei risultati del test "10 passati, 0 falliti, 1 saltato" è almeno un'indicazione che qualcosa è sospetto per le persone che non lo conoscono. Preferisco l' @Ignoreapproccio. La ragione per cui usare solo un commento non mi sembra una buona idea è perché non penso che le persone aprano spesso test unitari per controllarli (a meno che non stiano fallendo, o (si spera) quando si chiedono perché qualcosa viene saltato ).
Captain Man,

3

A seconda dello strumento di test è possibile utilizzare una funzione omito pend.

Esempio in rubino:

gem 'test-unit', '>= 2.1.1'
require 'test/unit'

MYVERSION = '0.9.0' #Version of the class you test 


class Test_omit < Test::Unit::TestCase
  def test_omit
    omit('The following assertion fails - it will be corrected in the next release')
    assert_equal(1,2)
  end

  def test_omit_if
    omit_if(MYVERSION < '1.0.0', "Test skipped for version #{MYVERSION}")
    assert_equal(1,2)
  end

end

Il omitcomando salta un test, lo omit_ifcombina con un test - nel mio esempio collaudo il numero di versione ed eseguo il test solo per le versioni in cui prevedo che l'errore sia stato risolto.

L'output del mio esempio è:

Loaded suite test
Started
O
===============================================================================
The following assertion fails - it will be corrected in the next release [test_omit(Test_omit)]
test.rb:10:in `test_omit'
===============================================================================
O
===============================================================================
Test skipped for version 0.9.0 [test_omit_if(Test_omit)]
test.rb:15:in `test_omit_if'
===============================================================================


Finished in 0.0 seconds.

2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
0% passed

Quindi la mia risposta: Sì, implementa il test. Ma non confondere un tester con errori, dove sai che fallirà.


2

Se il bug è fresco nella tua mente e hai il tempo di scrivere il test unitario ora, allora lo scriverei ora e lo contrassegnerei come un fallimento noto in modo che non fallisca la build stessa. Il tuo bug tracker dovrebbe essere aggiornato per riflettere che esiste un test unitario che al momento non riesce per questo bug in modo che la persona assegnata alla fine lo risolva, non lo riscrive di nuovo. Ciò suppone che il codice errato non abbia bisogno di molti refactoring e che l'API cambi in modo significativo - in tal caso, potrebbe essere meglio non scrivere il test unitario fino a quando non si ha una migliore idea di come deve essere scritto il test .


1

La risposta è NO IMHO. Non è necessario aggiungere un test unitario per il bug fino a quando non si inizia a lavorare sulla correzione per il bug e quindi si scriveranno i test che provano il bug e quando i test falliscono in conformità con la segnalazione dei bug ( s) andrai a correggere il codice effettivo per far passare i test e il bug verrà risolto e verrà coperto dopo.

Nel mio mondo avremmo un caso di test manuale in cui i QE falliscono fino a quando il bug non viene corretto. E noi come sviluppatori ne saremmo consapevoli tramite il manuale TC in errore e tramite il tracker dei bug.

La ragione per non aggiungere UT in errore è semplice. Le UT sono per feedback diretto e validazione di ciò che io come sviluppatore sto attualmente lavorando. E gli UT vengono utilizzati nel sistema CI per assicurarsi che non abbia infranto involontariamente qualcosa in un'altra area di codice per quel modulo. Avere gli UT che falliscono intenzionalmente per un bug noto IMHO sarebbe controproducente e semplicemente sbagliato.


0

Suppongo che la risposta sia davvero, dipende. Sii pragmatico al riguardo. Cosa ti guadagna ora a scriverlo? Forse è fresco nella tua mente?

Quando si corregge il bug, ha perfettamente senso dimostrare che esiste scrivendo un test unit che espone il bug. Quindi correggi il bug e il test unitario dovrebbe passare.

Hai tempo per scrivere il test unit fallito proprio ora? Esistono funzioni o bug più urgenti che devono essere scritti / corretti.

Supponendo che tu abbia un software di tracciamento dei bug competente con il bug registrato, non è davvero necessario scrivere il test dell'unità fallito in questo momento .

Probabilmente potresti creare un po 'di confusione se introduci un test unitario fallito prima di un rilascio che sta avvenendo senza la correzione di bug.


0

Di solito mi sento a disagio per aver riscontrato errori nelle suite di test, perché è troppo facile che l'elenco cresca nel tempo o che gli errori non correlati negli stessi test vengano liquidati come "previsti". Lo stesso vale per i guasti intermittenti: potrebbe esserci qualcosa di malvagio in agguato nel codice. Vorrei votare per aver scritto il test per il codice così com'è ora e come dovrebbe essere una volta che è stato risolto ma commentato o disabilitato in qualche modo.

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.