Ustal, co musisz przetestować, a co możesz wykluczyć.
W poprzednim artykule omówiliśmy podstawy przypadków testowych i ich zawartości. W tym artykule zagłębiamy się w procesie tworzenia przypadków testowych od strony technicznej i wyjaśniamy, co należy uwzględnić w każdym teście, a czego unikać. Ogólnie rzecz biorąc, nauczysz się odpowiedzi na najczęstsze pytania „Co testować” i „Czego nie testować”.
Ogólne wytyczne i wzorce
Warto zauważyć, że konkretne wzorce i punkty mają kluczowe znaczenie niezależnie od tego, czy przeprowadzasz testy jednostkowe, integracyjne czy kompleksowe. Zasady te mogą i powinny być stosowane do obu typów testowania, więc od nich najlepiej zacząć.
Trzymaj się prostych rozwiązań
Jedną z najważniejszych rzeczy, o których należy pamiętać podczas pisania testów, jest prostota. Ważne jest, aby wziąć pod uwagę wydajność mózgu. Główny kod produkcyjny zajmuje sporo miejsca, a jego obsługa jest niewielka. Dotyczy to zwłaszcza testowania.
Jeśli jest mniej miejsca, możesz się bardziej odprężyć podczas testów. Dlatego tak ważne jest, aby podczas testowania skupić się na prostocie. Sprawdzone metody testowania JavaScriptu Yoni Goldberg podkreślają znaczenie złotej reguły – test powinien poczuć się jak asystent, a nie jak skomplikowany wzór matematyczny. Inaczej mówiąc, od razu musisz wiedzieć, jaki jest cel testu.
Staraj się, by wszystkie rodzaje testów były jak najłatwiejsze, niezależnie od ich złożoności. Im bardziej skomplikowany jest test, tym ważniejsze staje się jego uproszczenie. Jednym ze sposobów osiągnięcia tego celu jest zastosowanie testów płaskich, w których są one jak najprostsze i sprawdzać tylko to, co jest konieczne. Oznacza to, że każdy test powinien obejmować tylko 1 przypadek testowy, który powinien dotyczyć tylko jednej, konkretnej funkcji lub funkcji.
Pomyśl o tym z tej perspektywy: gdy przeczytasz nieudany test, łatwo zorientować się, co poszło nie tak. Dlatego tak ważne jest, aby testy były proste i łatwe do zrozumienia. Dzięki temu możesz szybko wykrywać i rozwiązywać problemy, gdy się pojawią.
Sprawdź, czy warto
Płaski układ testów zachęca też do koncentracji i pomaga zadbać o trafność testów. Pamiętaj, że testy nie mają być tworzone tylko dla samej potrzeby – zawsze powinny mieć jakiś cel.
Nie testuj szczegółów implementacji
Jednym z częstych problemów podczas testowania jest to, że testy często służą do testowania szczegółów implementacji, takich jak używanie selektorów w komponentach lub w testach kompleksowych. Szczegóły implementacji dotyczą rzeczy, których użytkownicy kodu zwykle nie używają, nie widzą lub o których nawet nie wiedzą. Może to prowadzić do 2 głównych problemów w testach: wyników fałszywie negatywnych i fałszywych pozytywnych.
Wynik fałszywie negatywny występuje, gdy test się nie powiedzie, mimo że testowany kod jest prawidłowy. Może się tak zdarzyć, gdy szczegóły implementacji zmienią się w wyniku refaktoryzacji kodu aplikacji. Z drugiej strony, gdy test się zakończy, mimo że testowany kod jest nieprawidłowy.
Jednym z rozwiązań tego problemu jest rozważenie różnych typów użytkowników. Użytkownicy i deweloperzy mogą mieć inne podejście i wchodzić w interakcję z kodem w inny sposób. Podczas planowania testów należy brać pod uwagę to, co użytkownicy będą widzieć lub z którymi wchodzą w interakcje. Testy należy uzależniać od tych czynników, a nie od szczegółów implementacji.
Na przykład wybór selektorów, które są mniej podatne na zmiany, może zwiększyć wiarygodność testów: atrybuty data-attributes zamiast selektorów CSS. Więcej informacji znajdziesz w artykule Kent C. artykułu Dodds na ten temat lub bądź na bieżąco. Artykuł na ten temat pojawi się w późniejszym czasie.
Sztuczna inteligencja: nie trać kontroli
Imitacje to szerokie pojęcie stosowane w testach jednostkowych, a czasem także w testach integracyjnych. Obejmuje to tworzenie fałszywych danych lub komponentów w celu symulowania zależności zapewniających pełną kontrolę nad aplikacją. Umożliwia to przeprowadzanie izolowanych testów.
Stosowanie prób w testach może poprawić przewidywalność, odseparowanie potencjalnych problemów i zwiększyć skuteczność. Jeśli musisz przeprowadzić test, który wymaga udziału człowieka (np. weryfikacja paszportu), musisz ukryć go za pomocą sztuczki. Z tych wszystkich powodów makiety są cennym narzędziem, które warto wziąć pod uwagę.
Jednocześnie naśmiewanie się może wpływać na dokładność testu, ponieważ jest tylko żartem, a nie faktycznym doświadczeniem użytkownika. Musisz więc zachować ostrożność, używając imitacji.
Czy warto naśladować kompleksowe testy?
Ogólnie rzecz biorąc, nie. Naśmiewanie się może czasem uratować życie, więc nie wykluczajmy go całkowicie.
Wyobraź sobie taki scenariusz: piszesz test funkcji wykorzystującej usługę zewnętrznego dostawcy usług płatniczych. Znajdujesz się w środowisku piaskownicy, który zapewnił serwer, co oznacza, że nie są realizowane żadne prawdziwe transakcje. Piaskownica działa nieprawidłowo, co powoduje, że testy kończą się niepowodzeniem. Rozwiązaniem musi zająć się dostawca usług płatniczych. Możesz tylko poczekać na rozwiązanie problemu przez usługodawcę.
W takim przypadku korzystniejsze może być zmniejszenie zależności od usług, nad którymi nie masz kontroli. Zalecamy ostrożne stosowanie żartów podczas testów integracji lub testów kompleksowych, ponieważ zmniejsza to wiarygodność testów.
Szczegóły testu: co robić, a czego nie
Co zatem zawiera test? Czy są między nimi różnice? Przyjrzyjmy się bliżej niektórym aspektom dostosowanym do głównych typów testów.
Co należy do dobrego testu jednostkowego?
Idealny i efektywny test jednostkowy powinien:
- Skoncentruj się na konkretnych aspektach.
- Działają niezależnie.
- Uwzględnij scenariusze na małą skalę.
- Używaj nazw opisowych.
- W razie potrzeby stosuj się do wzorca AAA.
- Gwarancja kompleksowych testów.
Tak ✅ | Nie ❌ |
---|---|
Testy powinny być jak najmniejsze. Przetestuj jedną rzecz w każdym przypadku testowym. | Pisanie testów w dużych jednostkach. |
Należy zawsze przeprowadzać testy w izolacji i symulować potrzebne dane, które znajdują się poza jednostką. | Uwzględnij inne komponenty lub usługi. |
Dbaj o niezależność testów. | Polegaj na poprzednich testach lub udostępniaj dane testowe. |
Omów różne scenariusze i ścieżki. | Ogranicz się do szczęśliwej ścieżki albo do testów negatywnych. |
Używaj opisowych tytułów testowych, aby od razu wiedzieć, czego dotyczy test. | Przetestuj tylko nazwę funkcji. Z tego powodu jej opis nie jest wystarczająco opisowy: testBuildFoo() lub testGetId() . |
Staraj się uzyskać dobry zasięg kodu lub szerszy zakres przypadków testowych, zwłaszcza na tym etapie. | Testowanie od każdej klasy aż do poziomu bazy danych (I/O). |
Co należy do dobrego testu integracji?
Idealny test integracji ma takie same kryteria jak testy jednostkowe. Jest jednak kilka dodatkowych kwestii, które należy wziąć pod uwagę. Świetny test integracji powinien:
- Symulowanie interakcji między komponentami.
- Omawiaj rzeczywiste sytuacje i korzystaj z przykładów.
- Weź pod uwagę wydajność.
Tak ✅ | Nie ❌ |
---|---|
Przetestuj punkty integracji: sprawdź, czy poszczególne jednostki poprawnie ze sobą współdziałają. | Przetestuj każdą jednostkę osobno. Do tego służą testy jednostkowe. |
Przetestuj rzeczywiste scenariusze: użyj danych testowych opartych na danych ze świata rzeczywistego. | Używaj powtarzalnych automatycznie generowanych danych testowych lub innych danych, które nie odzwierciedlają rzeczywistych przypadków użycia. |
Używaj symulowanych zależności zewnętrznych, aby zachować kontrolę nad pełnym testem. | tworzenie zależności od usług innych firm, na przykład żądań sieciowych wysyłanych do usług zewnętrznych; |
Stosuj rutynę czyszczenia przed każdym testem i po nim. | Zapomnij o stosowaniu metod czyszczenia w testach, ponieważ może to doprowadzić do niepowodzeń lub wyników fałszywie pozytywnych z powodu braku odpowiedniej izolacji testu. |
Co należy do dobrego kompleksowego testu?
Kompleksowy test powinien:
- Powielanie interakcji użytkowników.
- Uwzględniaj najważniejsze scenariusze.
- Rozmieść wiele warstw.
- Zarządzaj operacjami asynchronicznymi.
- Sprawdź wyniki.
- Bierz pod uwagę skuteczność.
Tak ✅ | Nie ❌ |
---|---|
Używaj skrótów opartych na interfejsie API. Więcej informacji | Na każdym etapie użyj interakcji w interfejsie, w tym punktu zaczepienia beforeEach . |
Przed każdym testem przeprowadź rutynę czyszczenia. Zadbaj o izolację testów w większym stopniu niż w przypadku testów jednostkowych i integracji, ponieważ istnieje większe ryzyko wystąpienia efektów ubocznych. | Zapomnij o sprzątaniu po każdym teście. Jeśli nie wyczyścisz pozostałego stanu, danych ani efektów ubocznych, będzie to miało wpływ na inne testy, które zostaną wykonane później. |
Kompleksowe testy należy traktować jako testy systemu. Oznacza to, że musisz przetestować cały stos aplikacji. | Przetestuj każdą jednostkę osobno. Do tego służą testy jednostkowe. |
Ogranicz do minimum lub w ogóle nie naśmiewaj się w teście. Zastanów się, czy chcesz imitować zależności zewnętrzne. | W dużej mierze polegają na żartach. |
Rozważ zastosowanie wydajności i obciążenia, na przykład przez nieprzetestowanie dużych scenariuszy w ramach jednego testu. | Obsługuj duże przepływy pracy bez używania skrótów. |