Wpis z mikrobloga

Mam apkę w #java. Kiedy w IDE jako listę argumentów podaję null to oczywiście apka wywala NullPointerExeption. Jeśli jednak odpalić tę samą apkę w CMD i nie podać żadnych argumentów, to wtedy już rzucony zostaje ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0. Dlaczego tak się dzieje? Czy takie zachowanie w ogóle powinno zostać przetestowane? Jeśli tak to w jaki sposób?

public static void main(String[] args) {

String pat = args[0];
String txt = args[1];

PatternSearch searcher = new PatternSearch(pat);
int offset = searcher.search(txt);

System.out.println("offset:" + offset);
}

#naukaprogramowania #programowanie #bdd #tdd #cucumber
  • 16
  • Odpowiedz
@69inch:

Dlaczego tak się dzieje


Bo w jednym przypadku robisz tablicę z jednym nullowm elementem a w drugim pustą tablicę.

Czy takie zachowanie w ogóle powinno zostać przetestowane? Jeśli tak to w jaki sposób?


No powinieneś przetestować. Testem jednostkowym np. Do przetwarzania listy argumentów powinieneś sobie jakąś klasę zrobić i tę klasę testujesz.
  • Odpowiedz
Jeśli jednak odpalić tę samą apkę w CMD i nie podać żadnych argumentów, to wtedy już rzucony zostaje ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0. Dlaczego tak się dzieje?


@69inch: tablica argumentów jest pusta, ciekawe dlaczego nie mogę z niej wybrać pierwszego elementu?
  • Odpowiedz
Czy takie zachowanie w ogóle powinno zostać przetestowane? Jeśli tak to w jaki sposób?


@69inch: możesz przenieść logikę wyciągania argumentów do innej klasy i tam przetestować ten kod w izolacji. Dobrym pomysłem jest przetestowanie takiej aplikacji konsolowej end-to-end: zamiast wołać kod na poziomie Javy po prostu odpalasz twój program w taki sposób jak robi to użytkownik. Jako wejście podajesz argumenty, jako wyjście otrzymujesz to co zostanie wypisane + kod błędu. Dzięki
  • Odpowiedz
@Saly: @LazyInitializationException: O ile dobrze was zrozumiałem to powinienem stworzyć zupełnie nową klasę tylko do obsługi listy argumentów ale tu pojawia się inny problem. Hipotetycznie będąc testerem coś takiego jest w ogóle dozwolone? Czy ingerencja w kod nie jest dozwolona tylko dla devów?
  • Odpowiedz
@LazyInitializationException: W takim razie tylko z perspektywy testera, którego zadaniem jest przetestowanie apki metodą BDD czy takie zachowanie jak rzucenie wyżej wymienionego wyjątku powinno być przetestowane? Czy to już należy do deva i powinno być uwzględnione w testach jednostkowych?
  • Odpowiedz
@69inch: Tester patrzy z punktu widzenia użytkownika. To, że w sytuacji X ma być zgłoszony wyjątek to jest szczegół implementacyjny. Tester patrzy czy działają wszystkie funkcje i czy nie da się popsuć aplikacji.

W tym przypadku uruchomienie aplikacji bez parametrów albo z jakimiś parametrami z dupy to byłoby coś na co tester zwróciłby uwagę. Tylko, że tester obchodziłoby to, czy aplikacja się nie wykrzaczy i będzie jakiś sensowny komunikat
  • Odpowiedz
@69inch: logika parsowania argumentów jest logiką typowo związaną z tym, że twój program jest aplikacją konsolową. Według mnie nie warto wymyślać cuda w unit testach, bo to nie jest logika, którą można wyekstrachować do jakiegoś oddzielnego kodu. Możesz zobaczyć, czy wpisanie złego argumentu rzuci wyjątek, ale po co? Lepiej to samo przetestować na żyjącej aplikacji. Użytkownika nie interesuje wyjątek tylko to jak aplikacja się zachowa. Jak masz dobre testy end-to-end to
  • Odpowiedz
@LazyInitializationException: No więc właśnie, po odpaleniu apki bez argumentów albo z parametrami z dupy widzę, że wyjątek zostaje rzucony, jednak to nie jest nigdzie zaimplementowane w kodzie.
Stąd mój problem jak to powinno być przetestowane. Bo gdyby to było zaimplementowane to dałoby się to określić asercjami, ponieważ nie jest i jako tester nie mogę ingerować w kod, nie widzę tutaj czego powinienem się chwycić. Szczególnie, że gdy próbuję użyć asercji dla
  • Odpowiedz
@Saly: Rozumiem, że użytkowania nie interesuje rzucony wyjątek i powinienem przetestować zachowanie ale właśnie o to mi chodzi, że z tego co ja rozumiem to w tym przypadku jedyny sposób to przetestowania zachowania aplikacji jest sprawdzenie czy konkretny wyjątek jest rzucony.

Stąd cały problem, wiem, że z perspektywy usera jest bez znaczenia czy to NullPointer czy ArrayIndex. Po prostu po wpisaniu złego argumentu aplikacja przestaje działać. Wydaje mi się, że asercja
  • Odpowiedz
@69inch: jak chcesz przetestować ten kod unitowo to najlepiej przenieść całą logikę parsowania do osobnej klasy, która będzie miała metodę Arguments parseArguments(String ...args) throws ArgumentParsingException. I zrób tak, żeby rzucać wyjątek przed wyciąganiem elementu z tablicy, gdy się okaże, że tablica jest za mała. ArgumentParsingException to oczywiście osobny typ wyjątku, który musisz stworzyć
  • Odpowiedz
@Saly: Ok, to rozumiem. Jednak to mi wygląda na ingerencję w kod. Co w momencie gdy chcę przetestować w BDD bez ingerowania w kod?
  • Odpowiedz
@69inch: nie da się. Testy jednostkowe testują wydzielony kawałek kodu, w twoim kodzie nie ma czegoś takiego. Musisz testować end-to-end
  • Odpowiedz
@Saly: @LazyInitializationException: Nie wiem czy was to zainteresuje więc z góry sorki za wołanie ale siedziałem nad tym kodem i z pomocą SO wymyśliłem, żeby z metody testowej za pomocą ProcessBuilder odpalić cmd.exe, a w nim jeszcze raz cmd.exe już wraz ze ścieżką do aplikacji i komendą, która nie zawiera parametrów. Po puszczeniu testu widzę, że konsola się odpala i jest w niej rzucony wyjątek ArrayIndexOutOfBoundsException więc chyba działa. Niestety
  • Odpowiedz