JUnit: jak uniknąć „niemożliwych do uruchomienia metod” w klasach narzędzi testowych


118

Przerzuciłem się na JUnit4.4 z JUnit3.8. Uruchamiam testy za pomocą programu Ant, wszystkie testy przebiegają pomyślnie, ale klasy narzędzi testowych kończą się niepowodzeniem z błędem „Brak metod do uruchomienia”. Wzorzec, którego używam, polega na umieszczeniu wszystkich klas o nazwie * Test * w folderze testowym.

Rozumiem, że biegacz nie może znaleźć żadnej metody z adnotacją @Test. Ale nie zawierają takiej adnotacji, ponieważ te klasy nie są testami. Zaskakujące jest to, że uruchamiając te testy w zaćmieniu, nie narzeka na te klasy.

W JUnit3.8 nie był to żaden problem, ponieważ te klasy narzędziowe nie rozszerzały TestCase, więc runner nie próbował ich wykonać.

Wiem, że mogę wykluczyć te konkretne klasy z docelowego junit w skrypcie Ant. Ale nie chcę zmieniać pliku kompilacji przy każdej nowej klasie narzędzi, którą dodam. Mogę też zmieniać nazwy zajęć (ale nadawanie klasom dobrych nazw zawsze było moim najsłabszym talentem :-))

Czy jest jakieś eleganckie rozwiązanie tego problemu?


Czy twoje testy działają w Eclipse / NetBeans / twoim ulubionym IDE?
— guerda

Używam zaćmienia. Właściwie nie ma w tym problemu, jakoś eclipse nie próbuje uruchomić tych klas. Zastanawiam się jak?
— LiorH

Nie wiem, czy zrozumieliśmy twoje pytanie. Przeczytaj ponownie swoje pytanie i prawdopodobnie dodaj więcej informacji.
— guerda

1
@guerda: Pytanie wydaje mi się całkiem jasne. Jego zadaniem Ant jest znalezienie klas, które nie zawierają testów, ponieważ filtr wybiera klasę użytkową. Stąd moja odpowiedź, która nadal uważam za całkowicie aktualną.
— Jon Skeet

LiorH: Dziękuję za wyjaśnienie, więc moja odpowiedź to marnotrawstwo :)
— guerda

Odpowiedzi:


50

Zakładając, że masz kontrolę nad wzorcem używanym do znajdowania klas testowych, sugerowałbym *Testraczej zmianę go tak, aby pasował *Test*. W ten sposób TestHelpernie zostanie dopasowany, ale FooTestbędzie.


1
Nie sądzę, żeby to pomogło, ponieważ przeniósł się na JUnit 4.4 i to nie powinno mieć znaczenia.
— guerda

2
Wydaje się, że przegapiłeś sens mojej odpowiedzi. Ma filtr nazw, który określa klasy, które mają być traktowane jako testy. Jeśli zmieni filtr, może łatwo wykluczyć klasy pomocnicze.
— Jon Skeet

1
Twoja sugestia jest słuszna, jednak sprawdziłem moje zajęcia z testów i niektóre zaczynają się od testu, a niektóre kończą na teście. brak wyraźnego rozróżnienia między klasami użytkowymi a prawdziwymi klasami testowymi. Czy uważasz, że zaproponowana przez Ciebie konwencja jest dobrą praktyką? (tj. narzędzia zaczynają się od Test, a testy kończą się od Test)
— LiorH

4
Prawie konwencją jest dodawanie sufiksu do klas testcase z * Test. Może zajść potrzeba refaktoryzacji, odpowiednio zmieniając nazwy klas testowych, a także zmieniając nazwy pomocników, aby nie używały tej konwencji sufiksu.
— Spoike,

2
Zgadzam się ze Spoike - jeśli nie możesz stwierdzić z nazwy klasy, czy to test, czy pomocnik, powinieneś zmienić nazwę klasy. Konwencja jest bardziej „klasa jest testem wtedy i tylko wtedy, gdy kończy się na Test”. Klasy narzędziowe mogą, ale nie muszą rozpoczynać się od testu - to nie ma znaczenia.
— Jon Skeet

142

Dodaj adnotacje do swoich klas użytkowych za pomocą @Ignore. Spowoduje to, że JUnit nie będzie próbował uruchamiać ich jako testów.


6
Właściwie nie, nie powinno. @Ignore służy do tymczasowego wyłączania testów.
— Alice Young

1
Przepraszam, ale to zły pomysł. Chcesz zacząć dodawać adnotacje do kodu produkcyjnego za pomocą adnotacji związanych z testami tylko dlatego, że mogą one pasować do wzorca testowego? Prawidłową odpowiedzią jest poprawienie nazw klas, jeśli wyzwalają one dopasowywanie wzorców dla testów. I upewnij się, że wzorzec znajduje tylko klasy, które kończą się na Test. To powszechnie przyjęty wzorzec
— Kevin M

Tak, to jest złe i nie zdawałem sobie z tego sprawy, dopóki nie złożyłem kolejnego głosu za, którego nie mogę usunąć. Uczyń swoją klasę bazową abstrakcyjną, a JUnit ją zignoruje. Zobacz odpowiedź @ gmoore poniżej.
— Ryan Shillington,

83

Mój konkretny przypadek ma następujący scenariusz. Nasze testy

public class VenueResourceContainerTest extends BaseTixContainerTest

wszystko się wydłuża

BaseTixContainerTest

a JUnit próbował uruchomić BaseTixContainerTest. Biedny BaseTixContainerTest próbował tylko ustawić kontener, ustawić klienta, zamówić pizzę i zrelaksować się… stary.

Jak wspomniano wcześniej, możesz dodać do klasy adnotację

@Ignore

Ale to spowodowało, że JUnit zgłosił ten test jako pominięty (w przeciwieństwie do całkowicie zignorowanego).

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

To mnie irytowało.

Zrobiłem więc BaseTixContainerTest abstrakcyjnym, a teraz JUnit naprawdę to ignoruje.

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

7
Znacznie lepiej niż@Ignore
— neworld

Próbowałem podejście @Ignore i myśli, dobrze, że jest dobre, a potem czytam tę odpowiedź i klepnął się w czoło, „Of oczywiście !”
— dnuttle

38

Aby uniemożliwić JUnit utworzenie instancji testowej klasy bazowej, po prostu zrób to

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

(@Ignore zgłasza to jako ignorowane, które rezerwuję na tymczasowo ignorowane testy).


3
Programy uruchamiające JUnit często próbują również utworzyć instancję klas abstrakcyjnych, a następnie kończą się niepowodzeniem z powodu błędu instancji.
— Holly Cummins,

Działa idealnie dla moich podstawowych klas testowych
— ruX

3
To działa z powodu nazwy (nie kończy się na Test), a nie z powodu modyfikatora abstract. Zmień nazwę klasy na MyBaseClassTest i spróbuje utworzyć instancję, o której wspomniał @HollyCummins (i nie powiedzie się)
— Hutch

W moim przypadku tak powinno być protected abstract class.
— Mystic Lin

18
  1. Jeśli jest to Twoja podstawowa klasa testowa, na przykład AbstractTest, a wszystkie testy ją rozszerzają, zdefiniuj tę klasę jako abstrakcyjną
  2. Jeśli jest to klasa Util, lepiej usuń * Test z klasy zmień nazwę, to jest MyTestUtil lub Utils itp.

10

Zachowaj ostrożność, używając uzupełniania kodu IDE, aby dodać import dla @Test.

Musi być, import org.junit.Testa nie import org.testng.annotations.Testna przykład. Jeśli zrobisz to drugie, pojawi się błąd „brak uruchomionych metod”.


Powinien to być raczej komentarz niż odpowiedź.
— Swaranga Sarma

3
Nie rozumiem dlaczego. To prawidłowe rozwiązanie.
— Sridhar Sarnobat

4
Intellij Idea 2017 mieszał mi w głowie, importując org.junit.jupiter.api.Testzamiast tego! ale dzięki tobie jest już rozwiązany
— AmiNadimi

Dziękuję bardzo, byłem zdezorientowany podczas otrzymywania problemu „brak dostępnych metod”.
— Peter S.

7

Mrówka ma teraz skipNonTestsatrybut, który został zaprojektowany, aby robić dokładnie to, czego szukasz. Nie ma potrzeby zmieniania klas bazowych na abstrakcyjne lub dodawania do nich adnotacji.


2
Wygląda na to, że skipNonTestsatrybut jest dostępny tylko w mrówce 1.9+, a szkoda, bo wygląda niesamowicie użytecznie. Wyklucza również abstrakcyjne nadklasy testowe.
— Holly Cummins,

4

A co z dodaniem pustej metody testowej do tych klas?

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

8
ale to fałszywie zwiększa liczbę testów, które mamy :) nie to jest wielka sprawa
— Sudarshan

1

W Twojej klasie testowej, jeśli została napisana import org.junit.jupiter.api.Test; usuń go i napisz import org.junit.Test; W tym przypadku też mi się udało.


1
zadziwiające, zadziałało. wykonałem ręcznie w wierszu poleceń systemu Windows. jednak innym problemem jest to @BeforeAlli @AfterAllnie są one uruchamiane.
— BingLi224

pozornie JUnit4 działał (z @BeforeClassi @AfterClass, ale JUnit5 nie. Źródła
— BingLi224

0

Miałem również do czynienia z podobnym problemem („brak metod do uruchomienia…”) przy uruchamianiu najprostszego z prostego fragmentu kodu (przy użyciu @Test, @Before itp.) I nigdzie nie znalazłem rozwiązania. Używałem Junit4 i Eclipse SDK w wersji 4.1.2. Rozwiązałem mój problem, używając najnowszego zestawu Eclipse SDK 4.2.2. Mam nadzieję, że pomoże to ludziom, którzy borykają się z podobnym problemem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.