Jaka jest różnica między strukturami testów jednostkowych ScalaTest i Scala Specs?

121

Oba są platformami testów jednostkowych obsługujących BDD (Behavior Driven Development) dla Scali, napisanymi w Scali. A Specyfikacja jest zbudowany na może również obejmować ScalaTest ramy. Ale czego nie oferuje specyfikacja ScalaTest? Jakie są różnice?

Alex
źródło
1
Nie sądzę, aby można było powiedzieć, że specyfikacja jest oparta na ScalaTest. Zauważ, że zależność w pom jest opcjonalna. Specs może jednak działać jako pakiet ScalaTest.
Geoff Reedy
scalatest zapewnia scalatestplus ze specjalną obsługą kilku bibliotek. to może być interesujące. na przykład mają scalatestplus dla frameworka gry
pedrorijo91

Odpowiedzi:

172

Specs i ScalaTest to dobre narzędzia dla zadowolonych użytkowników, ale różnią się na kilka sposobów. Prawdopodobnie będziesz chciał wybrać jedno z nich jako główne narzędzie testowe w Scali, ale nie musisz rezygnować z drugiego, ponieważ możesz użyć fragmentów obu. Jeśli na przykład podoba Ci się FeatureSpecskładnia ScalaTest i składnia Mockito specyfikacji, możesz umieścić oba pliki jar w swojej ścieżce klas i używać obu jednocześnie. Tutaj spróbuję uchwycić główne różnice w filozofii projektowania, które zauważyłem między specyfikacjami a ScalaTest.

Prawdopodobnie główna różnica filozoficzna między tymi narzędziami polega na tym, że specyfikacje są przeznaczone do rozwoju opartego na zachowaniu (BDD), podczas gdy ScalaTest jest bardziej ogólny. ScalaTest zapewnia cechy, które można łączyć ze sobą, aby uzyskać preferowane zachowanie w klasach testowych, w tym BDD, a także można łatwo zdefiniować własne zachowanie, jeśli chcesz czegoś innego.

ScalaTest podpory BDD poprzez swoje Spec, FeatureSpec, WordSpec, FlatSpec, i GivenWhenThencechy, a także posiada cechy, które można mieszać w celu uzyskać ładny składnię dopasowujący. Jeśli lubisz „powinno”, mieszasz w ShouldMatchers. Jeśli lubisz „must”, wmieszaj się MustMatchers. Ale jeśli podoba ci się BDD, ale nie lubisz składni dopasowującej, możesz po prostu użyć jednej z cech Spec ScalaTest bez mieszania cechy dopasowującej. Specs ma klasę Specification, którą rozszerzasz i musisz użyć słowa „must” w swoich wyrażeniach dopasowujących. Widoczna tutaj duża różnica filozoficzna polega na tym, że ScalaTest daje dużo więcej możliwości wyboru. Aby ułatwić nawigację po tej przestrzeni wyboru, przedstawiam tutaj drzewo decyzyjne:

http://www.scalatest.org/quick_start

Składnia dopasowania różni się również w przypadku ScalaTest i specyfikacji. W ScalaTest próbowałem zobaczyć, jak daleko mogę się posunąć z notacją operatorową, i skończyło się na wyrażeniach dopasowujących, które czytają bardzo podobnie do zdań angielskich, ze spacjami między słowami. Składnia dopasowująca specyfikacje łączy słowa bardziej ze sobą w przypadku wielbłąda.

Specyfikacje mają więcej dopasowań niż ScalaTest i myślę, że odzwierciedla to różnicę w podejściu do projektowania. Właściwie usunąłem prawdopodobnie 2/3 składni dopasowującej, którą zbudowałem i rozważałem do wydania. Dodam więcej dopasowań w przyszłych wydaniach, ale chciałem się upewnić, że przed dodaniem czegoś użytkownicy rzeczywiście chcieli czegoś. Jednak dopasowania ScalaTest zawierają dynamiczną składnię dopasowującą właściwości, która zajmuje część tego luzu. Na przykład w Specyfikacjach możesz napisać na java.io.File:

file must beDirectory

Spowoduje to wywołanie isDirectoryi upewnienie się, że to prawda. ScalaTest nie ma obecnie żadnych specjalnych java.io.Filesdopasowań, ale w ScalaTest możesz po prostu użyć dynamicznej kontroli w następujący sposób:

file must be a ('directory)

Za każdym razem, gdy przekażesz symbol w after be, użyje on odbicia do wyszukania (w tym przypadku) metody lub pola o nazwie directorylub metody o nazwie isDirectory. Istnieje również sposób na uczynienie tego statycznym, definiując a BePropertyMatcher(co zwykle wymaga tylko 2 lub 3 wierszy kodu). Więc zasadniczo w ScalaTest staram się zapewnić większą funkcjonalność przy mniejszym API.

Inna ogólna różnica w podejściu projektowym między specyfikacjami a ScalaTest dotyczy niejawnych konwersji. Domyślnie uzyskujesz tylko jedną niejawną konwersję, gdy używasz ScalaTest, która jest tą, która umieszcza ===operator na wszystkim. (Jeśli potrzebujesz, możesz „wyłączyć” tę niejawną konwersję za pomocą jednej linii kodu. Jedynym powodem, dla którego musisz to zrobić, jest próba przetestowania czegoś, co ma własny ===operator, i wystąpi konflikt. ) ScalaTest definiuje wiele innych niejawnych konwersji, ale aby ich użyć, musisz jawnie „zaprosić” je do swojego kodu poprzez dodanie cechy lub wykonanie importu. Kiedy rozszerzasz klasęSpecificationw specyfikacjach myślę, że domyślnie otrzymujesz dziesiątki niejawnych konwersji. Nie jestem pewien, jak bardzo będzie to miało znaczenie w praktyce, ale myślę, że ludzie będą chcieli testować kod, który używa ich własnych implikacji, a czasami może wystąpić konflikt między implikacjami struktury testowej a kodem produkcyjnym. Kiedy tak się stanie, myślę, że łatwiej będzie obejść problem w ScalaTest niż w specyfikacji.

Kolejną różnicą w podejściu projektowym, którą zauważyłem, jest komfort obsługi. Jednym z celów, jakie miałem, było to, że każdy programista patrząc na kod testowy innej osoby, który używa ScalaTest, byłby w stanie odgadnąć, jakie jest znaczenie, bez szukania czegokolwiek w dokumentacji ScalaTest. Chciałem, aby kod klienta ScalaTest był zupełnie oczywisty. Jednym ze sposobów, w jaki cel ten się ujawnił, jest to, że ScalaTest jest bardzo konserwatywny w stosunku do operatorów. W ScalaTest definiuję tylko pięciu operatorów:

  • ===, co oznacza równe
  • >, co oznacza większe niż
  • <, mniej niż
  • >=, większe lub równe
  • <=mniejszy lub równy.

Otóż ​​to. Więc te rzeczy wyglądają jak to, co oznaczają. Jeśli widzisz w kodzie innej osoby:

result should be <= 7

Mam nadzieję, że nie będziesz musiał przechodzić do dokumentacji API, aby odgadnąć, co to <=oznacza. Z kolei specyfikacje są znacznie bardziej swobodne w przypadku operatorów. Nie ma w tym nic złego, ale to jest różnica. Operatorzy mogą uczynić kod bardziej zwięzłe, ale kompromis jest być może trzeba biec do dokumentacji, gdy znajdziesz takie rzeczy jak ->-, >>, |, |>, !, lub ^^^(które mają specjalne znaczenie w Specs) w pamięci kolegi kodu testowego.

Inną filozoficzną różnicą jest to, że staram się nieco ułatwić w ScalaTest używanie funkcjonalnego stylu, gdy trzeba udostępnić urządzenie, podczas gdy Specs domyślnie kontynuuje tradycję setUpi tearDownpodejście spopularyzowane przez JUnit, w którym ponownie przypisuje się zmienne przed każdym testem. Jeśli jednak chcesz przetestować w ten sposób, w ScalaTest jest to również bardzo łatwe. Wystarczy dodać BeforeAndAftercechę.

Aby uzyskać więcej informacji na temat ScalaTest, możesz obejrzeć prezentację „Get Higher with ScalaTest”, którą wygłosiłem na konferencji Devoxx 2009 tutaj:

http://parleys.com/play/514892260364bc17fc56bde3/chapter0/about

Bill Venners
źródło
6
Czytelność scalatest jest dla mnie główną zaletą w stosunku do specyfikacji Scala.
nemoo
49

Główne różnice to (głównie z punktu widzenia specyfikacji :-)):

  • ScalaTest zapewnia więcej „stylów testowania” niż specyfikacji (możesz odwiedzić każdy punkt na stronie szybkiego startu, aby uzyskać szczegółowy widok każdego stylu)

  • ScalaTest i specyfikacje mają inny zestaw dopasowań. Możesz je porównać tutaj dla ScalaTest i tutaj dla specyfikacji. Z drugiej strony specyfikacje mają wiele drobnych funkcji, które mogą Ci się spodobać podczas pisania specyfikacji: dopasowywanie xml, kompozycja dopasowań (łatwy sposób na ponowne wykorzystanie dopasowań poprzez ich przekształcenie), precyzyjne awarie, szczegółowe różnice dla długich ciągów, ... .

  • Mockito otrzymało niezłe wsparcie BDD w specyfikacji: Mockito

  • specyfikacje mają DataTables, które pozwalają grupować wiele małych przykładów w rodzaj tabeli (jeśli możesz ustawić operatory używane jako ograniczniki tabeli)

  • W specyfikacjach możesz zdefiniować przykłady, które są zagnieżdżone jako libidum i automatycznie czyszczone na każdym poziomie

Jest to z pewnością bardzo częściowe i stronnicze porównanie i istnieje wiele innych różnic (a biblioteki wciąż się rozwijają, ...).

Pod koniec dnia myślę, że to naprawdę zależy od twojego stylu testowania / określania. Jeśli jest to proste (prosta struktura specyfikacji, ustawienia, oczekiwania, ...), obie biblioteki będą wyglądać bardzo podobnie. W przeciwnym razie obaj mają swoje zdanie na temat tego, jak należy to zrobić. Jako ostatni przykład możesz przyjrzeć się tagowaniu: w ScalaTest oraz w specyfikacjach .

Mam nadzieję, że to pomoże.

Eric
źródło
Czy byłoby możliwe zaktualizowanie tego, aby obejmowało specyfikację 2? :)
Joffer
5

O ile mi wiadomo, pomijając kilka wysoce wyspecjalizowanych funkcji, sprowadza się to do osobistych preferencji w zależności od stylu.

Daniel C. Sobral
źródło
2

Wsparcie dla IDE może być kolejnym punktem

Próbowałem zmusić Specs do współpracy z Eclipse przez JUnit i uznałem, że oficjalne rozwiązanie jest trochę "hackowe". Konfiguracja specyfikacji: http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse

Integracja ScalaTest (również przez JUnit) z wydaje się nieco mniej skomplikowana. Mimo to nie mam żadnego z nich do pracy tak dobrze jak JUnit i Java.

Konfiguracja ScalaTest: http://groups.google.com/group/scalatest-users/web/running-scalatest-from-eclipse

Grav
źródło
Otrzymuję teraz 404 dla tego linku ScalaTest. Wypróbuj scalatest.org/user_guide/using_junit_runner
DNA
0

Jeśli jednym z czynników decyzyjnych jest czas kompilacji, scalatest wydaje się działać lepiej.

Obecnie używamy specyfikacji specs2 w naszym projekcie, ale w testach cierpimy z powodu długich czasów kompilacji. Właśnie ukończyłem POC na temat przejścia na scalatest i zauważyłem, że czasy kompilacji spadły o współczynnik około 0,82 po prostu przez zmianę dwóch frameworków w niektórych naszych źródłach.

sebi
źródło