2009-09-02 15 views
7

Obecnie ponownie używam testów JUnit 4 z innego projektu przeciwko mojemu kodowi. Dostaję je bezpośrednio z repozytorium innego projektu w ramach mojej zautomatyzowanej wersji Ant. To wspaniałe, ponieważ zapewnia zachowanie zielonego kodu w stosunku do najnowszej wersji testów.Wyklucz indywidualne metody testowe JUnit bez modyfikowania klasy Test?

Istnieje jednak podzbiór testów, w których nigdy nie spodziewam się przekazania mojego kodu. Ale jeśli zacznę dodawać adnotacje @Ignore do tych testów, będę musiał zachować własną oddzielną kopię implementacji testowej, której naprawdę nie chcę robić.

Czy istnieje sposób wykluczenia poszczególnych testów bez modyfikowania źródła testu? Oto co mam spojrzał na tak daleko:

  • O ile widzę, zadanie Ant JUnit tylko pozwala wykluczyć całych klas test, a nie poszczególne metody badań - więc to nie jest dobre dla mnie, muszę ziarnistość metody.

  • Zastanawiałem się nad połączeniem TestSuite, które używa refleksji, aby dynamicznie znaleźć i dodać wszystkie oryginalne testy, a następnie dodać kod, aby wyraźnie usunąć testy, których nie chcę uruchamiać. Ale porzuciłem ten pomysł, gdy zauważyłem, że TestSuite API nie zapewnia metody usuwania testów.

  • Potrafię tworzyć własne klasy testowe, które rozszerzają oryginalne klasy testowe, zastępują określone testy, których nie chcę uruchamiać, i dodam je do adnotacji przy pomocy @Ignore. Następnie uruchom JUnit na moich podklasach. Wadą jest to, że jeśli nowe klasy testowe zostaną dodane do oryginalnego projektu, nie będę ich automatycznie pobierał. Będę musiał monitorować nowe klasy testów, ponieważ są one dodawane do oryginalnego projektu. To moja najlepsza opcja, ale nie czuję się idealnie.

  • Jedyna inna opcja, o której mogę pomyśleć, to uruchomić złe testy i zignorować awarie. Jednak te testy trwają długo (i nieudane!), Więc wolałbym ich w ogóle nie uruchamiać. Ponadto nie widzę sposobu, aby powiadomić zadanie Ant, aby zignorowało niepowodzenia dotyczące określonych metod testowania (ponownie - widzę, jak można to zrobić dla poszczególnych klas testowych, ale nie metod).

Odpowiedz

4

Jeśli nie możesz dotknąć pierwotnego testu, będziesz miał poważne ograniczenia. Twoje nadpisanie brzmi jak najlepszy zakład, ale z kilkoma zmianami:

Zbuduj testy Ant, w szczególności wykluczając super klasy, aby dodatkowe klasy, o których nie wiesz, zostały uruchomione.

Możesz użyć adnotacji @Rule (nowy w JUnit 4.7), aby wiedzieć, który test jest uruchamiany i przerwać go (zwracając pustą implementację instrukcji), zamiast nadpisywać określone metody, co daje większą elastyczność w ustaleniu, czy aby uniknąć testu. Jedynym problemem związanym z tą metodą jest to, że nie można zatrzymać metod @ Begore przy użyciu tej metody, która może być wolna. Jeśli jest to problem (i naprawdę nie możesz dotknąć testów), to jedyne, co mogę wymyślić, to @Ignore w nadpisanej metodzie.

Jeśli jednak można dotknąć tych badań, niektóre dodatkowe opcje otwarcia:

Można je uruchomić z niestandardowym biegacza określając tag @RunWith od klasy. Ten biegacz po prostu przekazałby wykonanie do standardowego biegacza (JUnit4.klasa) w tym projekcie, ale w twoim projekcie (poprzez właściwość systemową lub jakiś inny mechanizm) sprawdzałby nazwę testu, a nie przeprowadzał testu. Ma to tę zaletę, że jest najmniej inwazyjną, ale najtrudniejszą do zrealizowania (biegacze to owłosione bestie, jednym z wyznaczonych celów @Rule było wyeliminowanie większości z konieczności ich wykonania).

Innym jest założenie, że to stwierdzenie w teście, które sprawdzi pewne ustawienia konfiguracyjne, które byłyby prawdziwe, gdyby test ten działał. To w rzeczywistości wymagałoby wstrzyknięcia bezpośrednio do testu, co jest najprawdopodobniej złamaniem umowy w czymkolwiek, co można by nazwać "oddzielnym projektem".

0

Jeśli niechciane testy znajdują się w określonych klasach/pakietach, można użyć zestawu wykluczeń zestawu plików w aplikacji Ant, aby wykluczyć je podczas importu.

+0

Nie, niestety muszę wykluczyć konkretne metody testowania. Oznacza to, że chcę przeprowadzić testy w danej klasie testowej, ale nie w innych. – rewbs

2

OK, to jest raczej ciężkie rozwiązanie, ale nie rzucaj we mnie rzeczami, jeśli brzmi to niedorzecznie.

Rdzeniem Junit4 jest klasa org.junit.runner.Runner i jej różne podklasy, a przede wszystkim org.junit.runners.Suite. Biegacze określają, jakie testy są dla danej klasy testowej, używając rzeczy takich jak @Test i @Ignore.

Utworzenie niestandardowych implementacji runnera jest dość łatwe. Zazwyczaj można je podłączyć za pomocą adnotacji @RunWith w klasie testowej, ale oczywiście nie jest to opcja dla ciebie.

Jednak teoretycznie można napisać własne zadanie Ant, być może w oparciu o standardowe zadanie Ant Junit, które przenosi niestandardową funkcję testową i wykorzystuje ją bezpośrednio, przekazując kolejno każdą klasę testową. Twoja implementacja runner może korzystać z zewnętrznego pliku konfiguracyjnego, który określa, które metody testowania mają zostać zignorowane.

To byłaby spora praca, a ty musiałbyś spędzić czas na kopaniu w prehistorycznym kodzie Ant Junit, aby dowiedzieć się, jak to działa. Inwestycja w czas może być jednak tego warta.

Szkoda tylko, że zadanie Junit Ant nie zapewnia mechanizmu określającego Runner testu, który byłby idealny.

+0

Powiedziałbym, że wdrażanie biegacza jest zwodniczo proste. Znalazłem się kopiowanie i wklejanie kodu z innych części JUnit, aby uzyskać niestandardowe, aby działał prawidłowo, i było bardzo kruche - prawie gwarantowane, aby złamać na nowej wersji. – Yishai

+0

Wszystko prawda. Nigdy nie twierdziłem, że to było eleganckie :) – skaffman

1

Możliwością, którą mogę wymyślić, aby osiągnąć to, co chcesz, z podanymi ograniczeniami, jest użycie modyfikacji kodu bajtowego. Możesz zachować listę klas i metod do zignorowania w oddzielnym pliku i załączyć bajt kodu klas testowych podczas ładowania, aby całkowicie usunąć te metody.

Jeśli się nie mylę, JUnit używa refleksji, aby znaleźć metody testowe do wykonania. Operacja zmiany nazwy metody umożliwiłaby usunięcie tych metod, zanim JUnit je znajdzie. Lub metodę można zmodyfikować, aby natychmiast wrócić, bez wykonywania żadnych operacji.

Biblioteka taka jak BCEL może być użyta do modyfikacji klas po załadowaniu.

+1

JUnit 4 używa adnotacji zamiast nazw metod do określenia testów do uruchomienia. – Yishai

+0

Byłoby nadal ważne, aby zmienić metodę, aby natychmiast powrócić. Ale dziękuję, myślałem o JUnit3 –

+2

Przypuszczalnie modyfikacja kodu bajtowego może być również użyta do dodania adnotacji @Ignore do metod w klasach skompilowanych. – rewbs

3

To nie pomaga teraz, ale TestNG obsługuje tego rodzaju zdolności.

1

Jeśli chcesz uruchomić tylko podzestaw testów, to brzmi, jakby ta klasa miała więcej niż jedną odpowiedzialność i powinna zostać ponownie przetworzona. Alternatywnie klasa testowa może zostać rozbita, tak aby oryginalny projekt miał wszystkie testy, ale na jednej lub kilku klasach (domyślam się, że niektóre testy są rzeczywiście testami integracyjnymi i dotykają bazy danych lub sieci) i można wykluczyć klasę (es) nie chciałeś.

Jeśli nie możesz tego zrobić, prawdopodobnie opcja nadpisania jest najlepsza. Wykonaj proces za każdym razem, gdy chcesz zignorować niektóre metody rozszerzenia tej klasy i dodać ją do listy wykluczeń Ant. W ten sposób możesz wykluczyć to, czego nie możesz zaliczyć i nadal będziesz pobierać wszystkie nowe testy (metody, których nie zastąpiłeś i nowe klasy testowe) bez modyfikowania kompilacji.

0

dwie opcje

  1. Pracuj z właścicielem pożyczonych testów wyodrębnić te, do osobnej klasy można zarówno dzielić.
  2. Utwórz własną klasę testów, która jest odpowiednikiem klasy testowej, której chcesz użyć. Dla każdej metody, którą chcesz uwzględnić, masz metodę na swojej klasie. Będziesz musiał skonstruować instancję klasy testowej, do której dzwonisz, i zrobić to przed i po metodach, jeśli są w oryginale.
  3. Utwórz niestandardowy biegacz Junit oparty na blockjunitrunner i użyj go do odfiltrowania lub w testach, które chcesz.