assert vs. JUnit Assertions

85

Dzisiaj widziałem przypadek testowy JUnit z asercją Java zamiast asercji JUnit - czy istnieją istotne zalety lub wady preferowania jednego nad drugim?

Robert
źródło
Istnieją absolutnie rzeczowe różnice między asercjami JUnit a słowem kluczowym „assert” w języku Java. To wcale nie jest kwestia opinii.
Thomas W

Odpowiedzi:

95

W JUnit4 wyjątek (właściwie Error) zgłoszony przez potwierdzenie JUnit jest taki sam, jak błąd wyrzucony przez assertsłowo kluczowe java (AssertionError), więc jest dokładnie taki sam, jak assertTruei inny niż ślad stosu, którego nie można było odróżnić.

To powiedziawszy, potwierdzenia muszą działać ze specjalną flagą w JVM, co powoduje, że wiele testów wydaje się zakończonych pomyślnie tylko dlatego, że ktoś zapomniał skonfigurować system z tą flagą, gdy testy JUnit były uruchamiane - niedobrze.

Generalnie z tego powodu argumentowałbym, że korzystanie z JUnit assertTruejest lepszą praktyką, ponieważ gwarantuje wykonanie testu, zapewnia spójność (czasami używasz assertThatlub innych potwierdzeń, które nie są słowem kluczowym Java) i jeśli zachowanie JUnit stwierdza powinien się zmienić w przyszłości (np. podłączenie do jakiegoś rodzaju filtru lub innej przyszłej funkcji JUnit), twój kod będzie w stanie to wykorzystać.

Prawdziwym celem słowa kluczowego assert w java jest możliwość wyłączenia go bez kary w czasie wykonywania. Nie dotyczy to testów jednostkowych.

Yishai
źródło
26

Preferuję asercje JUnit, ponieważ oferują bogatsze API niż wbudowana assertinstrukcja i, co ważniejsze, nie muszą być jawnie włączane, w przeciwieństwie do tego assert, co wymaga -eaargumentu JVM.

Adamskiego
źródło
1
-eajest zawsze włączony mvn test, nie ma potrzeby -ea. Bogatszy interfejs API, dobry chwyt. Czasami myślę, że API jest niewłaściwie używane w teście, ponieważ nie jest częścią aplikacji (a in api), wolę nazywać to po prostu bogatszymi metodami.
Ponury
19

Gdy test się nie powiedzie, otrzymasz więcej informacji.

assertEquals(1, 2); prowadzi do java.lang.AssertionError: expected:<1> but was:<2>

vs

assert(1 == 2); prowadzi do java.lang.AssertionError

możesz uzyskać jeszcze więcej informacji, dodając argument wiadomości do assertEquals

starmer
źródło
9
spróbuj assert 1==2: "1 is not 2";.
Ponury,
@PeterRader Wypróbuj słowo kluczowe assert, gdy opcja -ea nie jest włączona. Albo jeszcze lepiej, użyj asercji JUnit, które zawsze działają.
Thomas W,
1
@ThomasW gdy opcja -ea nie jest włączona, to nie jest test. Aseracje JUnit nie zawsze działają, działają tylko wtedy, gdy zdecydujesz się użyć JUnit, co jest frameworkiem, aw przypadku maven zależność maven, zależność maven, która musi znajdować się tylko w zakresie testowym. Mamy tu dwie strony: co wolisz? Pierwsza strona : Użyj frameworka, jako zależności tylko w zakresie testowym, który musi zostać pobrany, to zaćmienie pozwala ci używać w klasach, które nie znajdują się w src / main-folder, ale nie będą tam kompilowane, ponieważ maven mają junit tylko w test- zakres lub druga strona : użyj wbudowanych rzeczy.
Ponury
1
@PeterRader To pytanie dotyczy przypadków testowych JUnit. W tym kontekście należy użyć JUnit lub podobnej klasy asercji, ponieważ są one zawsze włączone. Osobiście złapało mnie słowo kluczowe „assert” w Javie, które nie było włączone w przeszłości i nie wierzę, że niewiarygodne asercje mają miejsce w kodzie testowym.
Thomas W
W oddzielnym kontekście asercji w kodzie funkcji - ważnych dla solidnej praktyki programistycznej, choć w rzeczywistości nie jest to temat pytania - zarówno Spring, jak i Google Guava mają klasy asercji, które są zawsze włączone. Zalecam hojne korzystanie z nich jako warunków wstępnych parametrów i stanu, aby zapewnić poprawność. Poza tym, w obszarach krytycznych dla wydajności, nie może być mały obszar gdzie Java assertmoże być korzystne - poprawności kontroli, które będą miały wpływ wydajności, a zatem są najlepiej domyślnie wyłączone. Jednak z mojego doświadczenia wynika, że ​​większość twierdzeń powinna być zawsze włączona.
Thomas W
8

Powiedziałbym, że używaj potwierdzeń JUnit w przypadkach testowych i używaj asercji Java w kodzie. Innymi słowy, prawdziwy kod nigdy nie będzie miał zależności JUnit, co jest oczywiste, a jeśli jest to test, powinien używać jego odmian JUnit, a nie assert.

Bruno D. Rodrigues
źródło
0

Powiedziałbym, że jeśli używasz JUnit, powinieneś użyć asercji JUnit. assertTrue()jest w zasadzie to samo co assert, w przeciwnym razie po co w ogóle używać JUnit?

CheesePls
źródło
4
Używałbyś JUnit do testowania platformy. Aktywa to tak naprawdę niewielka część wartości, jaką oferuje JUnit. JUnit bez Assertwymagałby więcej kotłów. assertbez JUnit wymagałoby napisania całego frameworka.
Yishai
1
Bardziej mówiłem, że jeśli zamierzasz używać tego narzędzia, UŻYJ NARZĘDZIA. zwykłe, stare stwierdzenia assert wydają się trochę głupie w przypadkach testowych JUnit. Moim zdaniem należą one do właściwego kodu.
CheesePls
1
@CheesePls "Zwykłe stare oświadczenia assert" są w rzeczywistości nowsze niż twierdzi JUnit.
dolmen,
0

Może to nie mieć zastosowania, jeśli używasz wyłącznie rzeczy, które są błyszczące i nowe, ale funkcja assert została wprowadzona do Javy dopiero w 1.4SE. Dlatego jeśli musisz pracować w środowisku ze starszą technologią, możesz skłaniać się do JUnit ze względu na kompatybilność.

Dan Coates
źródło