Trochę kontekstu: Wcześniej musiałem zaktualizować kod SQL, który dostarczył inny mój kolega, a ponieważ jest to dość duży skrypt, jest on przechowywany jako osobny plik (który jest następnie odczytywany i uruchamiany w czasie wykonywania). Robiąc to, przez przypadek przywróciłem dwa błędy, które mieliśmy kilka miesięcy temu, a mianowicie:
- Z jakiegokolwiek powodu plik ASCII został zakodowany w UTF-16 (kolega przesłał mi plik, który mógł go spowodować).
- W skrypcie brakowało
SET
instrukcji początkowych (wymaganych z powodu niektórych sterowników podczas produkcji, ale nie podczas czystej instalacji lokalnie).
Po debugowaniu tego przez około godzinę (ponownie) postanowiłem napisać kilka testów jednostkowych, aby upewnić się, że to się nigdy nie powtórzy (i podaj szybki sposób, aby to naprawić w komunikacie asercji, aby zapewnić łatwą poprawkę dla przyszłych programistów).
Kiedy jednak pchnąłem ten kod, podszedł do mnie inny kolega (który jest również naszym szefem zespołu) i powiedział, że nie powinienem robić tych rzeczy ponownie, ponieważ:
„Te rzeczy nie należą do testów jednostkowych”
„Testy jednostkowe powinny być używane tylko do sprawdzania przepływu kodu”
Jestem teraz dość skonfliktowany, ponieważ nadal uważam, że to, co robię, nie jest złe, ponieważ ten błąd nie zostanie ponownie wprowadzony w przyszłości, jednak ten kolega pracuje jako starszy i pod koniec dnia może zdecydować, co spędzamy czas na. Co powinienem zrobić? Czy mylę się, że robię to w ten sposób? Czy jest to uważane za złą praktykę?
źródło
Odpowiedzi:
Najprawdopodobniej napisane przez ciebie testy są bliższe testom integracji lub regresji niż testom jednostkowym. Chociaż linia może być bardzo rozmyta i czasami przechodzi w pedanterię nad tym, co jest testem jednostkowym, ale nie wrócę do twojego kolegi i zapytam, gdzie powinny być napisane testy, ponieważ zapewniają one wartość dodaną, zapewniając poprawność kodu.
Nie skupiałbym się zbytnio na tym, co jest testem jednostkowym, a czym nie jest, i zdałem sobie sprawę, że nawet jeśli jest to test integracyjny, w teście może być jeszcze wartość.
źródło
Z technicznego punktu widzenia nie jest to test jednostkowy, a raczej etap weryfikacji. Właściwe podejście naprawdę zależy od przepływu pracy. Kierownik zespołu ma rację co do celu testów jednostkowych. Mam wrażenie, że jest to przypadek użycia niewłaściwego narzędzia do pracy, która wciąż musi zostać wykonana. Zacznij od tego:
Przy opisie musisz sprawdzić, czy wszystkie skrypty bazy danych są zgodne z niektórymi standardami.
Jakość kodu źródłowego jest zwykle sprawdzana za pomocą narzędzi do analizy statycznej . Jeśli nie masz narzędzia do analizy statycznej do sprawdzania poprawności kodu SQL, możesz utworzyć szybkie i brudne narzędzie, które sprawdza wszystkie przekazane do niego pliki SQL. Nie zaszkodzi sprawdzić, czy istnieją narzędzia analizy statycznej, które poradzą sobie z problemami, o których mówisz.
Jeśli utworzysz tę część infrastruktury kompilacji, taką jak włączenie jej do Jenkins lub coś w tym rodzaju, można ją zastosować do wszystkich plików SQL w projekcie.
Testy jednostkowe rozwiązują problem tylko dla bieżącego pliku.
To całkiem proste, rozmawiasz z liderem zespołu. Może on współpracować z właścicielem produktu, a ty w celu ustalenia ryzyka / nagrody za inwestowanie w oprzyrządowanie. Jeśli jest to prawdopodobnie problem jednorazowy, oprzyrządowanie prawdopodobnie byłoby nadmierne. Jeśli oprzyrządowanie do wychwytywania największych problemów jest łatwe, może być warto tylko do kontroli poczytalności.
Twój lider zespołu może mieć pewne pomysły, których ty (lub ja) nie wziąłem pod uwagę, które mogą lepiej rozwiązać problem.
źródło
Złą praktyką jest nazywanie testów dostępu do plików „Testami jednostkowymi”.
Niestety, jakie rodzaje testów istnieją i jak są zorganizowane, są całkowicie zależne od firmy. Musisz więc dowiedzieć się, jak Twoja firma obsługuje te testy.
Jeśli nie masz jeszcze sposobu na uruchomienie automatycznych testów innych niż testy jednostkowe, pragmatyczne podejście polega na oznaczeniu testów jednostkowych, które tak naprawdę nie są testami jednostkowymi, do momentu, gdy będziesz mieć ich wystarczająco dużo, aby dowiedzieć się, jaki rodzaj testy, które faktycznie masz / potrzebujesz. Następnie możesz zacząć organizować.
źródło
Michael Feathers mówi to w swojej książce Skutecznie działając ze starszym kodem:
Czy Twój test pomoże szybko zlokalizować błędy i działać szybko? Jeśli tak, zrób to! Jeśli nie, to nie rób tego! To takie proste!
To powiedziawszy, pracujesz w otoczeniu z innymi ludźmi i musisz się z nimi dogadać. Być może będziesz musiał zrobić to po swojemu, nawet jeśli prywatnie się z tym nie zgadzasz.
źródło
Czasami pisałem podobne testy dla plików kodu źródłowego, plików konfiguracyjnych i tak dalej. Nie nazwałbym ich testami jednostkowymi, ponieważ (a) uzyskują dostęp do systemu plików i mogą nie być ultraszybkie (b) nie dbam o to, czy są wykonywane przy każdym zameldowaniu (w przeciwieństwie do nocnego na Serwer CI).
Możesz nazwać je testami integracji; z pewnością są bliżej tej perspektywy niż testy jednostkowe.
Mój własny termin dla nich to testy zasobów . IMHO są całkowicie uzasadnione, jeśli są wykonywane co noc na serwerze CI: są minimalne koszty, a przy rozsądnym użyciu wyraźnie zwiększają wartość. Jedna definicja rozsądnego : jeśli test sprawdza problem, który spowodował problem (taki jak wspomniane kodowanie).
źródło
Test jednostkowy polega na testowaniu metody lub „jednostki” kodu. Testujesz najmniejszą grupę logiki i kodu w swoim oprogramowaniu.
Później, kiedy dołączysz do tego z innymi jednostkami, przeprowadzisz testy integracji.
Mam nadzieję, że szef zespołu zachęcił do inicjatywy i powinien był zaproponować alternatywne propozycje. Zdecydowanie masz dobry pomysł.
Twój SQL jest kodem, podobnie jak każdy język niższej generacji, taki jak C # lub Java, i jako taki powinien zostać przetestowany. A weryfikacja i walidacja należą do wszystkich poziomów testowania. Tak więc kodowanie i instrukcje SET są uwzględnione, ale niekoniecznie wyłącznie testowane. Ogólne rzeczy, takie jak zakończenia linii lub zamykanie, zwykle można po prostu użyć haka SCM lub funkcji.
Najlepszą praktyką jest przeprowadzenie testów regresji, aby upewnić się, że wcześniejsze błędy nie zostaną ponownie wprowadzone. Zasadniczo testy są tworzone przy dowolnej rozdzielczości błędu. Jeśli te błędy nie są objęte testami regresji na poziomie jednostki / integracji lub systemu, a następnie ponownie wprowadzone, jest to problem zespołowy, procesowy, a nie indywidualny.
Chodzi o to, że ... błędy składniowe, brakujące instrukcje lub bloki logiczne wewnątrz „jednostki” zwykle nie są testowane. Testujesz wejścia i wyjścia urządzenia w różnych kombinacjach, testując wiele możliwości, które można wygenerować.
Wracając do brakujących instrukcji SET - pomagają poinformować o wielu możliwościach wejścia i wyjścia do testowania. Jaki test napisalibyście, że NIE POWINIENEŚ, gdybyście pominęli dowolny wybrany ZESTAW?
źródło
Jeśli masz pliki, które stają się częścią Twojego produktu, ich zawartość musi być poprawna. Nie ma powodu, dla którego nie zweryfikowałbyś tego. Na przykład, jeśli potrzebujesz sześciu 1024 x 1024 obrazów w jakimś folderze, to napisz test jednostkowy, który sprawdzi, czy dokładnie to masz.
Ale prawdopodobnie nie masz tylko plików, masz także kod, który czyta pliki. Możesz napisać test jednostkowy dla tego kodu. W powyższym przykładzie funkcja odczytu jednego z sześciu obrazów zwraca do pamięci obraz 1024 x 1024 (lub cokolwiek, co miałby wytworzyć).
W każdym razie może to nie być test jednostkowy, ale jest to test przydatny. A jeśli używasz szkieletu testu jednostkowego, który pozwala ci przeprowadzić użyteczny test (który nie jest testem jednostkowym), dlaczego nie użyć szkieletu testu jednostkowego?
źródło
Być może nie rozumiem twojego problemu, ale dla mnie to brzmi jak problem, który nie powinien być przechwytywany przez jakiś dedykowany test, ale po prostu przez system kontroli wersji . Każda zmiana w bazie kodu powinna zostać sprawdzona po poprawce przed zatwierdzeniem. Prostym sposobem na to w git jest dodanie zmian za pomocą
Spowoduje to, że dla każdej zmiany w pliku tekstowym katalog roboczy zapyta, czy naprawdę chcesz go zachować. Umożliwiłoby to na przykład usunięcie tych „wstępnych
SET
stwierdzeń”.Gdyby kodowanie całego pliku uległo zmianie, wydarzyło się coś innego: algorytm nie rozróżniałby starego i nowego pliku, a zatem
git add -p
nie dodałby niczego. Byłoby to wtedy widoczne w innym poleceniu, które wykonałbym przed jakimkolwiek zatwierdzeniem, mianowicieKtórą tu widać plik podświetlony na czerwono, co oznacza, że są zmiany. Badanie, dlaczego nie udało się tego zrobić,
git add -p
szybko uwidoczniłoby problem.źródło
git
jest najlepszym tego przykładem - doskonałym narzędziem, ale ledwo nadającym się do użytku dla zwykłych śmiertelników .Pod innym kątem do rozważenia: skoro te dwa warunki są wymagane do uruchomienia programu, nie powinieneś osadzić logiki blisko logiki wykonania? Mam na myśli: testujesz istnienie pliku przed jego odczytaniem i / lub weryfikujesz jego zawartość, prawda? więc jak to jest inaczej? Myślę, że ponieważ jest to zewnętrzny zasób kodu, powinien zostać sprawdzony w czasie wykonywania, zanim zostanie faktycznie użyty. Wynik: silniejsza aplikacja, nie trzeba pisać dodatkowych testów.
źródło
Testy mają taki sam kod jak każdy inny i, jeśli są wystarczająco złożone, również korzystają z ... testów jednostkowych. Najprostszym wydaje się dodanie takich kontroli warunków wstępnych bezpośrednio do testu.
Większość testów jest wystarczająco prosta, aby tego nie wymagać, ale jeśli niektóre są wystarczająco złożone, nie widzę nic zasadniczo złego w tych kontrolach warunków wstępnych. Oczywiście test powinien również zakończyć się niepowodzeniem bez nich, ale dobry test jednostkowy informuje również, która jednostka zawodzi.
Skrypt używany jako część testu, który musi mieć określoną treść i kodowanie, jest prawdopodobnie jednostką. Może mieć znacznie więcej kodu i logiki niż reszta testu. Test z takim skryptem nie jest najlepszym projektem w historii i, jeśli to możliwe, powinien zostać przekształcony w coś bardziej bezpośredniego (chyba że jest to test integracyjny).
źródło
Po pierwsze - jednym z celów testów jest zapobieganie powtarzaniu się problemów w kodzie - dlatego absolutnie powinieneś pisać testy tego rodzaju.
Po drugie - nazywanie jest trudne. Tak, wyraźnie nie są to „testy jednostkowe”, ale mogą być pożądanymi i niezbędnymi częściami procesu kompilacji, ponieważ chronią cię przed oczywistymi błędami i ponieważ szybciej informują cię o błędach (zwłaszcza, że nie widzisz konsekwencje dla dev box).
Tak więc pytanie naprawdę brzmi (powinno być w twoim kontekście) bardziej o tym, kiedy i jak te testy są uruchamiane, niż czym one są.
W przeszłości korzystałem z tego rodzaju testów - zaoszczędzili nam sporo bólu.
źródło
Testy jednostkowe polegają na wykonywaniu pojedynczej jednostki kodu w celu potwierdzenia, że generuje poprawny wynik dla prawidłowego wejścia. Izolacja powinna sprawić, że zarówno testowana jednostka, jak i sam test będą powtarzalne, tj. Nie powinny zależeć od efektów ubocznych ani ich wprowadzać.
SQL nie jest dokładnie czymś, co można przetestować w oderwaniu, więc każdy test SQL nie jest dokładnie testem jednostkowym i, z wyjątkiem instrukcji SELECT, prawie na pewno wywoła efekt uboczny. Możemy to nazwać testem integracyjnym, a nie testem jednostkowym.
Zawsze rozsądnie jest zapewnić, aby każda wada, która może zostać wprowadzona, mogła zostać wykryta jak najwcześniej w cyklu rozwojowym, a korzystne jest, aby zrobić to w sposób ułatwiający zidentyfikowanie źródła wady, aby można było szybko poprawione.
Testy, o których mowa, mogą być bardziej odpowiednio przeniesione poza ciało „testów jednostkowych” i umieszczone gdzie indziej, ale nie należy ich całkowicie usuwać, jeśli robią coś pożytecznego, jak ochrona przed możliwym wprowadzeniem usterki, której śledzenie może zająć wiele godzin. na dół.
źródło