Testy sparametryzowane - kiedy i dlaczego ich używasz?

15

Ostatnio w pracy mamy pewne różnice zdań w odniesieniu do testowania sparametryzowanego . Zwykle używamy stylu TDD (lub przynajmniej próbujemy), więc rozumiem zalety tego podejścia. Walczę jednak, by przynieść sparametryzowane testy wzmocnienia. Dla odniesienia pracujemy nad usługą i jej bibliotekami, które są udostępniane przez interfejs RESTful.

Do tej pory widziałem testy, które przynajmniej wykorzystują JUnit w Eclipse:

  • Brak szczegółów - gdy test się nie powiedzie, bardzo trudno jest dostrzec parametry, które go spowodowały
  • Często skomplikowane w tworzeniu
  • Zwykle są tworzone po napisaniu kodu - absolutnie nie jest to wada sama w sobie, ale czy ludzie wyruszają z myślą o sparametryzowanych testach, kiedy zaczynają fragment kodu?

Jeśli ktoś ma jakieś przykłady tego, gdzie są naprawdę przydatne, lub nawet jakieś dobre wskazówki, jak z nich korzystać, byłoby fantastycznie. Chcę się upewnić, że nie jestem uparty, ponieważ osobiście nie wybieram ich używania i sprawdzam, czy są czymś, co powinniśmy rozważyć, biorąc udział w naszym arsenale testowym.

neilprosser
źródło
1
Problemem nie jest pomysł, ale niezgrabna biblioteka. W języku C # składnia jest o wiele bardziej przyjazna, gdy używasz powiedz MbUnit. Tak, to dobry pomysł. Dodaj własny kod, aby ułatwić ten proces - odczytaj rzeczy z plików - cokolwiek działa. Zobacz także, jak MsTest sobie z tym radzi.
Job
My (Square) napisaliśmy Burst, aby rozwiązać niektóre z tych problemów Parameterized. Zazwyczaj dodaje mniej płyty kotłowej i wyraźnie pokazuje, gdzie test się nie powiódł.
Daniel Lubarov

Odpowiedzi:

4

Problem z testowaniem dowolnego oprogramowania polega na tym, że złożoność rozwija się dość szybko. Faktem jest, że nie można przetestować wszystkich możliwych kombinacji parametrów przekazanych do metod. Phadke opowiada się za podejściem do projektowania eksperymentów (DOE), które umożliwia generowanie prawdopodobnej listy wartości parametrów, które należy przetestować.

Chodzi o to, że nawet jeśli nie przeprowadzasz wyczerpujących testów, większość defektów powoduje pojawienie się „obszaru uszkodzenia”, a nie uszkodzenia pojedynczego punktu. Podejście DOE Phadke opowiada się za wykorzystaniem tablic ortogonalnych próbkujących przestrzeń parametrów wystarczająco dokładnie, aby trafić we wszystkie możliwe obszary błędów.

Pojedyncze uszkodzenia prawdopodobnie nie zostaną zidentyfikowane, ale na ogół jest ich mniej niż obszary uszkodzeń.

Podejście DOE zapewnia systematyczny sposób wyboru wartości parametrów do zmiany.

Peter K.
źródło
Podany link jest uszkodzony.
Josh Gust
1
@JoshGust Łatwo naprawić za pomocą Google. Dzięki za heads-upy.
Peter K.,
4

Mogą być przydatne do zapewnienia, że ​​Twój kod obsługuje nie tylko ścieżkę szczęśliwą, ale także przypadki brzegowe. Gdy już wiesz, że Twój kod działa ze zmiennymi normalnymi, sparametryzuj przypadek testowy i upewnij się, że wartości zerowe i zerowe, puste ciągi, duże liczby, długie ciągi, dziwne znaki Unicode itp. Również działają dobrze.

Ethel Evans
źródło
2

Istnieją co najmniej dwa warianty sparametryzowanych testów, przynajmniej w JUnit 4.8. Są to: Testy sparametryzowane ( @RunWith(Parameterized.class)), które wymagają źródła danych, które generuje / odczytuje predefiniowane konfiguracje parametrów, oraz Teorie ( @RunWith(Theories.class)), które przy danym jednym lub większej liczbie możliwych danych wejściowych dla każdego typu argumentu mogą wykonywać specyfikację danych metod. Wygląda mniej więcej tak:

  • podaj możliwe wartości ( @DataPoints) dla argumentów ciągu (np. nullpusty ciąg, niepusty ciąg, naprawdę długi ciąg)
  • podać kilka możliwych wartości ( @DataPoints) dla argumentów klasy zwierzę (jak null, Doginstancja, Catinstancja, Birdnp)
  • przygotuj, @Theoryktóry akceptuje Stringparametr i Animalparametr. zostanie wykonany z każdą możliwą kombinacją możliwych wartości parametrów (w podanym przykładzie byłoby to 4x4 = 16 kombinacji, w tym ( null, null))
  • jeśli testowana metoda nie może zaakceptować jakiejś kombinacji, użyj Assume.assumeThatimportu statycznego, aby odfiltrować nieprawidłowe kombinacje (np. gdy chcesz sprawdzić zachowanie metody dla niepustych ciągów znaków, jedną z pierwszych linii będzie „załóż, że nie jest pusta”

Jak napisano wcześniej - nie ma sensu testować każdej możliwej kombinacji każdej metody (rozbija zestawy testowe, wyobraź sobie testowanie metody z 5 parametrami, z których każdy ma tylko 5 możliwych wartości: 5 ** 5 -> ponad 3000 testów !), ale w przypadku metod krytycznych dla misji (takich jak metody API) zachęcam do tego, aby być po bezpiecznej stronie ...

Adam Hepner
źródło
1

Ogólny przykład:

  • Metody z argumentami łańcuchowymi. Użyj sparametryzowanych testów do przetestowania różnych danych wejściowych i ich oczekiwanych wyników. O wiele bardziej praktyczne jest posiadanie listy par (dane wejściowe, oczekiwane) niż pisanie TC dla każdej pary.

  • Zastosuj ten sam scenariusz do różnych argumentów. Mamy scenariusz, który działa z Animalobiektu i mają wiele podklas, takich jak Dog, Cat, Bird. Utwórz listę dostępnych zwierząt i przetestuj na nich scenariusz.

Beton do usługi internetowej:

  • Z powyższego przykładu argumentów łańcuchowych. Sprawdź, co dzieje się z różnymi argumentami tego samego typu, ale o różnych wartościach.
Victor Hurdugaci
źródło
0

Testy sparametryzowane dobrze sprawdzają się w testowaniu funkcji / funkcji, które mają proste dane wejściowe, gdy chcesz przetestować różne dane wejściowe.

Nie działają dobrze do testowania różnych funkcji i skomplikowanych danych wejściowych. Nie należy ich używać jako struktury wygodnej do pisania mniej kodu.

Cirem
źródło
1
Dlaczego parametrów nie należy używać jako wygody do pisania mniej kodu? Nie ma wielkiej cnoty w dostarczeniu wyczerpującej listy dużego (ish) zestawu przypadków testowych.
Jonathan Eunice,
1
W jaki sposób twoja odpowiedź zawiera więcej informacji niż pozostałe 5 odpowiedzi?
Adam Zuckerman
-2

Jednym z przypadków, w których korzystam z wielu sparametryzowanych testów w sposób TDD, jest pisanie parserów - mogę zacząć od listy, jeśli dane wejściowe i oczekiwane dane wyjściowe, a następnie napisać kod, aby przekazać wszystkie przypadki testowe.

Ale widziałem kilka okropności sparametryzowanych testów. Nie, Virginia, twój zestaw testów nie powinien potrzebować własnych testów jednostkowych.

Wyatt Barnett
źródło
1
Idealnie sparametryzowane testy powinny mieć postać „czy pozycja (n) w rzeczywistym wyniku odpowiada pozycji (n) w oczekiwanym wyniku” lub podobnym, w takim przypadku nie jest wymagane testowanie. Ale dla czegoś bardziej złożonego wolałbym widzieć czysty sparametryzowany test lub dwa z ich własnymi przypadkami testowymi niż zwykłe falowanie ręczne „mój (testowy) kod jest oczywiście poprawny”. Gdyby to była prawda, w ogóle nie pisałbyś przypadków testowych. Oczywiście można przesadzić ze złożonością i nie twierdzę, że nie ma linii, ale myślę, że są przypadki, w których testowanie testów jest dobrym pomysłem.