Mamy system, w którym oprócz kodu Java działa kilka skryptów bash. Ponieważ próbujemy przetestować wszystko, co mogłoby się zepsuć, a te skrypty bash mogą się zepsuć, chcemy je przetestować.
Problem w tym, że trudno jest testować skrypty basha.
Czy istnieje sposób lub najlepsza praktyka testowania skryptów bash? A może powinniśmy przestać używać skryptów bash i poszukać alternatywnych rozwiązań, które można przetestować?
Odpowiedzi:
W rzeczywistości istnieje shunit2 , oparty na xUnit framework do testów jednostkowych dla skryptów powłoki opartych na Bourne. Sam tego nie używałem, ale może warto to sprawdzić.
Podobne pytania zadawano już wcześniej:
źródło
Otrzymałem następującą odpowiedź z grupy dyskusyjnej:
Ta metoda przypomina wstrzykiwanie zależności dla skryptów i wydaje się rozsądna. Preferowane jest unikanie skryptów bash i używanie bardziej testowalnego i mniej niejasnego języka.
źródło
Testowanie Bash zgodne z TAP : automatyczny system testowania Bash
nietoperz-rdzeń
źródło
Nikita Sobolev napisał doskonały wpis na blogu, w którym porównuje kilka różnych struktur testowych basha: Testowanie aplikacji Bash
Dla niecierpliwych: konkluzją Nikity było użycie Bats, ale wydaje się, że Nikita przegapił projekt Bats-core , który wydaje mi się być tym, który powinien być używany w przyszłości, ponieważ oryginalny projekt Bats nie był aktywnie utrzymywany od 2013 roku.
źródło
Epoxy to framework testowy Bash, który zaprojektowałem głównie do testowania innego oprogramowania, ale używam go również do testowania modułów bash, w tym siebie i Carton .
Główne zalety to stosunkowo niski narzut kodowania, nieograniczone zagnieżdżanie asercji i elastyczny wybór asercji do weryfikacji.
Zrobiłem prezentację porównującą to z BeakerLib - frameworkiem używanym przez niektórych w Red Hat.
źródło
Dlaczego mówisz, że testowanie skryptów bash jest „trudne”?
Co jest nie tak z opakowaniami testów, takimi jak:
źródło
Stworzyłem shellspec ponieważ chciałem łatwego w użyciu i użytecznego narzędzia.
Został napisany przez czysty skrypt powłoki POSIX. Testował z wieloma pociskami bardziej niż shunit2. Ma potężne funkcje niż nietoperze / rdzeń nietoperzy.
Na przykład obsługa zagnieżdżonych bloków, łatwe do makiety / odgałęzienia, łatwe do pominięcia / oczekujące, testy sparametryzowane, numer linii asercji, wykonanie według numeru linii, wykonywanie równoległe, wykonywanie losowe, formatowanie TAP / JUnit, integracja pokrycia i CI, profiler itp. .
Zobacz demo na stronie projektu.
źródło
Bardzo podoba mi się shell2junit , narzędzie do generowania danych wyjściowych w stylu JUnit z testów skryptów Bash. Jest to przydatne, ponieważ wygenerowany raport może być następnie odczytany przez systemy ciągłej integracji, takie jak wtyczki JUnit dla Jenkins i Bamboo.
Chociaż shell2junit nie zapewnia kompleksowego środowiska skryptowego Bash, takiego jak shunit2 , pozwala na ładne raportowanie wyników testów.
źródło
Wypróbuj bashtest . To prosty sposób na przetestowanie skryptów. Na przykład możesz
do-some-work.sh
zmienić niektóre pliki konfiguracyjne. Na przykład dodaj nową linięPASSWORD = 'XXXXX'
do pliku konfiguracyjnego/etc/my.cfg
.Piszesz polecenia basha wiersz po wierszu, a następnie sprawdzasz wyjście.
Zainstalować:
Tworzenie testów to po prostu pisanie poleceń basha.
Plik
test-do-some-work.bashtest
:Uruchom testy:
Możesz znaleźć kilka przykładów tutaj i tutaj
źródło
Może można to wykorzystać lub przyczynić się do tego
https://thorsteinssonh.github.io/bash_test_tools/
Przeznaczony do zapisywania wyników w protokole TAP, który moim zdaniem jest dobry dla CI i dobry dla tych, którzy chcą środowisk powłoki. Wyobrażam sobie, że niektóre rzeczy działają w środowisku powłoki, więc niektórzy mogą twierdzić, że należy je przetestować w środowisku powłoki.
źródło
Spróbuj assert.sh
Mam nadzieję, że to pomoże!
źródło
Nie mogę uwierzyć, że nikt nie mówił o BHP ! Jest kompatybilny zarówno z TAP, jak i JUnit, jest czystą powłoką (to znaczy nie obsługuje innych języków), działa również samodzielnie, jest prosty i bezpośredni.
Testowanie wygląda następująco (fragmenty pobrane ze strony projektu):
Prosty bieg:
Ostatni test pokazuje, że nie jest w porządku, ale kod zakończenia ma wartość 0, ponieważ jest to plik
TODO
. Można również ustawić gadatliwość:Zmień jego nazwę, aby używać
.t
rozszerzenia i umieść go wt
podkatalogu, a możesz użyćprove(1)
(części Perla), aby go uruchomić:Ustaw
OSHT_JUNIT
lub przeprowadź,-j
aby wygenerować wyjście JUnit. JUnit można również łączyć zprove(1)
.Użyłem tej biblioteki zarówno do testowania funkcji, pozyskując ich pliki, a następnie uruchamiając asercje z
IS
/OK
i ich negacjami, a także skrypty za pomocąRUN
/NRUN
. Dla mnie ta struktura zapewnia największy zysk przy najmniejszym nakładzie pracy.źródło
Wypróbowałem wiele przedstawionych tutaj rozwiązań, ale większość z nich okazała się nieporęczna i trudna w użyciu, więc zbudowałem własny mały framework testowy: https://github.com/meonlol/t-bash
To tylko jeden plik w repozytorium, który możesz po prostu uruchomić bezpośrednio, z podstawowym zestawem potwierdzeń w stylu JUnit.
Użyłem go profesjonalnie w kilku wewnętrznych projektach i udało mi się sprawić, że nasze skrypty bash są bardzo stabilne i odporne na regresję.
źródło
Możesz rzucić okiem na bash_unit:
https://github.com/pgrange/bash_unit
źródło
Spójrz na Outthentic , jest prosty, rozszerzalny o wiele języków (Perl, Python, Ruby, Bash na wybór) i wieloplatformowy (Linux, Windows) framework do testowania dowolnych aplikacji wiersza poleceń.
źródło
Trudno mi było usprawiedliwić używanie basha dla większych skryptów, gdy Python ma tak ogromne zalety:
if [ x"$foo" = x"$bar"]; then ...
”, która jest podatna na błędy.getopt
modułu (i jest jeszcze łatwiejszy moduł do analizowania argumentów, ale nazwa mi umyka).mysql
polecenia w bash, ale nie jest to najładniejszy sposób pisania kodu).$*
lub"$*"
lub"$@"
lub$1
lub"$1"
spacje w nazwach plików nie jest problemem, etc, etc, etc.Teraz używam basha tylko dla najprostszych skryptów.
źródło
if [[ $foo = $bar ]]; then ...
. To wciąż nie jest lepsze niż to, co ma do zaoferowania Python, ale jest lepsze niż to, co przedstawiłeś.trap
(aby wyczyścić / cofnąć w przypadku błędu), jak również wyrażenie regularne (tj[[ $1 =~ ^[1-3]{3}$ ]]
.). Jestem prawie pewien, że niejasna składnia, której użyłeś, odnosi się do starych implementacjitest
bash, a nie do bash. Bash świetnie nadaje się do łączenia się z istniejącymi narzędziami wiersza poleceń ... Często pojedynczy potok doawk
lubgrep
jest znacznie łatwiejszy niż alternatywa dla Pythona.optparse
lub jego następcaargparse
. Nigdy nie widziałem nikogo, kto używa tegogetopt
modułu, ani nie używałem go osobiście.getopt
Narzędzie to jest jednak wielka. Parsowanie argumentów z powłoki nie stanowi żadnego problemu, jeśli masz już ładny wzór. O ile nie próbujesz zaimplementować komend podrzędnych w stylu git lub czegoś takiego, nie jest to duży problem.