JUnit: come evitare "nessun metodo eseguibile" nelle classi di utilità di test


118

Sono passato a JUnit4.4 da JUnit3.8. Eseguo i miei test utilizzando ant, tutti i miei test vengono eseguiti correttamente ma le classi di utilità di test falliscono con l'errore "Nessun metodo eseguibile". Il modello che sto utilizzando consiste nell'includere tutte le classi con nome * Test * nella cartella di test.

Capisco che il corridore non riesce a trovare alcun metodo annotato con l'attributo @Test. Ma non contengono tale annotazione perché queste classi non sono test. Sorprendentemente, quando si eseguono questi test in eclipse, non si lamenta di queste classi.

In JUnit3.8 non era affatto un problema poiché queste classi di utilità non estendevano TestCase quindi il runner non ha provato a eseguirle.

So di poter escludere queste classi specifiche nel target junit in ant script. Ma non voglio cambiare il file di build su ogni nuova classe di utilità che aggiungo. Posso anche rinominare le classi (ma dare buoni nomi alle classi è sempre stato il mio talento più debole :-))

Esiste una soluzione elegante per questo problema?


I tuoi test funzionano in Eclipse / NetBeans / il tuo IDE preferito?
guerda

Uso eclipse. In realtà non ci sono problemi lì, in qualche modo eclipse non cerca di eseguire queste classi. Mi domando come?
LiorH

Non so se abbiamo capito la tua domanda. Per favore rileggi la tua domanda e probabilmente aggiungi qualche informazione in più.
guerda

1
@guerda: la domanda mi sembra abbastanza chiara. Il suo compito per Ant è trovare classi che non contengono test, perché il filtro sta rilevando la classe di utilità. Da qui la mia risposta, che ancora credo sia del tutto pertinente.
Jon Skeet

LiorH: Grazie per il chiarimento, quindi la mia risposta è sprecata :)
guerda

Risposte:


50

Supponendo che tu abbia il controllo del pattern utilizzato per trovare le classi di test, suggerirei di cambiarlo in modo che corrisponda *Testpiuttosto che *Test*. In questo modo TestHelpernon verrà abbinato, ma lo FooTestfarà.


1
Non credo che aiuterebbe, perché è passato a JUnit 4.4 e questo non dovrebbe avere importanza.
guerda

2
Sembra che tu abbia perso il punto della mia risposta. Ha un filtro per nome per determinare le classi da considerare come test. Se cambia il filtro, può facilmente escludere le classi helper.
Jon Skeet

1
Il tuo suggerimento è valido, tuttavia ho controllato le mie classi di test e alcune iniziano con Test e altre terminano con Test. nessuna chiara distinzione tra classi di utilità e classi di test reali. Pensi che la convenzione che hai suggerito sia una buona pratica? (cioè le utilità iniziano con Test e le prove terminano con Test)
LiorH

4
È quasi una convenzione aggiungere * Test come suffisso alle classi testcase. Potrebbe essere necessario eseguire il refactoring rinominando le classi di test in modo appropriato e rinominare anche gli helper in modo che non utilizzino quella convenzione di suffisso.
Spoike

2
Sono d'accordo con Spoike: se non riesci a capire dal nome della classe se si tratta di un test o di un aiutante, dovresti rinominare la classe. La convenzione è più "la classe è un test se e solo se finisce con Test". Le classi di utilità possono o non possono iniziare con Test, non importa.
Jon Skeet

142

Annota le tue classi util con @Ignore. Ciò farà sì che JUnit non provi a eseguirli come test.


6
In realtà no, non dovrebbe. @Ignore serve per disabilitare temporaneamente i test.
Alice Young

1
Scusa ma è una cattiva idea. Vuoi iniziare ad annotare il tuo codice di produzione con annotazioni relative al test solo perché potrebbero corrispondere a un modello di test? La risposta corretta è correggere i nomi delle classi se stanno attivando la corrispondenza del modello per i test. E assicurati che il pattern trovi solo le classi che FINISCONO con Test. Questo è uno schema comunemente accettato
Kevin M

Sì, questo è negativo e non me ne sono reso conto fino a dopo aver contribuito con un altro voto positivo che non posso rimuovere. Rendi astratta la tua classe base, quindi JUnit la ignorerà. Vedi la risposta di @ gmoore di seguito.
Ryan Shillington

83

Il mio caso specifico ha il seguente scenario. I nostri test

public class VenueResourceContainerTest extends BaseTixContainerTest

tutti si estendono

BaseTixContainerTest

e JUnit stava cercando di eseguire BaseTixContainerTest. Il povero BaseTixContainerTest stava solo cercando di configurare il contenitore, configurare il client, ordinare della pizza e rilassarsi ... amico.

Come accennato in precedenza, puoi annotare la classe con

@Ignore

Ma ciò ha indotto JUnit a segnalare quel test come saltato (anziché completamente ignorato).

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

Questo mi ha irritato.

Quindi ho creato BaseTixContainerTest astratto e ora JUnit lo ignora davvero.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

7
Molto meglio di@Ignore
neworld

Ho provato l'approccio @Ignore e ho pensato, bene che è un bene, poi ho letto questa risposta e mi diede una pacca sulla fronte, "Ma naturalmente !"
navetta

38

Per impedire a JUnit di creare un'istanza della tua classe base di test, creala

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore lo segnala come ignorato che riservo per test temporaneamente ignorati.)


3
I runner di JUnit spesso tentano di istanziare anche le classi astratte e poi falliscono con un errore di istanziazione.
Holly Cummins

Funziona perfettamente per le mie classi di test di base
ruX

3
Funziona a causa del nome (non finisce in Test), non a causa del modificatore astratto. Cambia il nome della classe in MyBaseClassTest e proverà a creare un'istanza come menzionato da @HollyCummins (e fallirà)
Hutch

Nel mio caso, dovrebbe essere protected abstract class.
Mystic Lin,

18
  1. Se questa è la tua classe di test di base, ad esempio AbstractTest e tutti i tuoi test lo estendono, definisci questa classe come astratta
  2. Se è la classe Util, è meglio rimuovere * Test dalla classe rinominare è MyTestUtil o Utils ecc.

10

Fai attenzione quando usi il completamento del codice di un IDE per aggiungere l'importazione @Test.

Deve essere import org.junit.Teste non import org.testng.annotations.Test, per esempio. In quest'ultimo caso, verrà visualizzato il messaggio di errore "nessun metodo eseguibile".


Questo dovrebbe essere un commento piuttosto che una risposta.
Swaranga Sarma

3
Non vedo perché. È una valida soluzione.
Sridhar Sarnobat

4
Intellij Idea 2017 mi stava incasinando la mente importando org.junit.jupiter.api.Testinvece! ma grazie a te ora è risolto
AmiNadimi

Grazie mille, ero confuso durante il problema "nessun metodo eseguibile".
Peter S.

7

Ant ora viene fornito con l' skipNonTestsattributo progettato per fare esattamente ciò che sembri cercare. Non è necessario modificare le classi di base per astrarle o aggiungervi annotazioni.


2
Sembra che l' skipNonTestsattributo sia disponibile solo in ant 1.9+, il che è un peccato, poiché sembra incredibilmente utile. Escluderà anche le superclassi di test astratte.
Holly Cummins

4

Che ne dici di aggiungere un metodo di test vuoto a queste classi?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
    assertTrue(true); // do nothing;
}

8
ma questo aumenta falsamente il numero dei test che abbiamo :) non che sia un grosso problema
Sudarshan

1

Nella tua classe di test se hai scritto import org.junit.jupiter.api.Test; cancellalo e scrivi import org.junit.Test; In questo caso ha funzionato anche per me.


1
sorprendentemente, ha funzionato. ho eseguito manualmente nella riga di comando di Windows. tuttavia, un altro problema è che @BeforeAlle @AfterAllnon vengono eseguiti.
BingLi224

apparentemente, JUnit4 ha funzionato (con @BeforeClasse @AfterClass, ma JUnit5 no. Riferimento: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224

0

Stavo anche affrontando un problema simile ("nessun metodo eseguibile ..") nell'esecuzione della parte di codice più semplice e semplice (utilizzando @Test, @Before ecc.) E non ho trovato la soluzione da nessuna parte. Stavo usando Junit4 e Eclipse SDK versione 4.1.2. Ho risolto il mio problema utilizzando l'ultima versione di Eclipse SDK 4.2.2. Spero che questo aiuti le persone che stanno lottando con un problema in qualche modo simile.

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.