Obliczenia w moim kodzie są dobrze przetestowane, ale ponieważ jest tak dużo kodu GUI, moje ogólne pokrycie kodu jest mniejsze niż bym chciał. Czy są jakieś wytyczne dotyczące kodu GUI do testów jednostkowych? Czy to w ogóle ma sens?
Na przykład w mojej aplikacji są wykresy. Nie byłem w stanie dowiedzieć się, jak zautomatyzować testowanie wykresów. Potrzeba ludzkiego oka, AFAIK, aby sprawdzić, czy wykres jest poprawny.
(Używam Java Swing)
unit-testing
user-interface
code-coverage
Steve McLeod
źródło
źródło
Odpowiedzi:
Projekty takie jak MVP i MVC zazwyczaj próbują wyodrębnić jak najwięcej logiki z rzeczywistego GUI. Bardzo popularnym artykułem na ten temat jest „The Humble Dialog Box” Michaela Feathersa. Osobiście miałem mieszane doświadczenia z próbami wyprowadzenia logiki z interfejsu użytkownika - czasami działało to bardzo dobrze, a innym razem sprawiało to więcej kłopotów, niż było warte. Jest to jednak trochę poza moim obszarem specjalizacji.
źródło
Oczywiście odpowiedzią jest użycie MVC i przeniesienie jak największej logiki z GUI.
To powiedziawszy, słyszałem od współpracownika dawno temu, że kiedy SGI przenosił OpenGL na nowy sprzęt, mieli kilka testów jednostkowych, które rysowały zestaw pierwotnych na ekranie, a następnie obliczały sumę MD5 bufora ramki. Wartość tę można następnie porównać ze znanymi dobrymi wartościami skrótu, aby szybko określić, czy interfejs API jest dokładny na piksel.
źródło
Możesz wypróbować UISpec4J to funkcjonalna i / lub biblioteka testów jednostkowych Open Source dla aplikacji Java opartych na Swing ...
źródło
Jest Selenium RC , które zautomatyzuje testowanie interfejsu użytkownika opartego na sieci. Będzie rejestrować działania i odtwarzać je. Nadal będziesz musiał przejść przez interakcje z interfejsem użytkownika, więc nie pomoże to w pokryciu, ale może być używane do automatycznych kompilacji.
źródło
Możesz spróbować użyć Cucumber and Swinger do pisania funkcjonalnych testów akceptacyjnych w prostym języku angielskim dla aplikacji Swing GUI. Swinger korzysta z biblioteki Jemmy Netbeans pod maską do obsługi aplikacji.
Ogórek pozwala pisać testy takie jak ten:
Obejrzyj demo wideo Swinger, aby zobaczyć, jak działa.
źródło
Oto kilka wskazówek:
Spróbuj usunąć jak najwięcej kodu z GUI (mieć kontroler i obiekt modelu) w ten sposób będziesz mógł je przetestować bez GUI.
W przypadku grafiki należy przetestować wartość, którą podajesz do kodu generującego grafikę.
źródło
Testowanie to forma sztuki. Zgadzam się, że logika powinna zostać usunięta z GUI tak bardzo, jak to możliwe. Wtedy możemy skupić się na naszych testach jednostkowych. Jak wszystko inne testowanie polega na zmniejszaniu ryzyka. Nie zawsze musisz wszystko testować, ale często najlepiej jest przerwać różne testy w różnych obszarach.
Drugie pytanie dotyczy tego, co tak naprawdę próbujesz przetestować w warstwie interfejsu użytkownika. Testowanie interfejsu użytkownika jest najdroższym testem, ponieważ zwykle trwa dłużej, aby go utworzyć, utrzymać i jest najbardziej kruchy. Jeśli przetestujesz logikę, aby wiedzieć, że współrzędne są poprawne, zanim spróbujesz narysować linię, co dokładnie testujesz? Jeśli chcesz przetestować wykres z czerwoną linią, rysuje się. Czy możesz podać mu ustalone z góry współrzędne i sprawdzić, czy określone piksele są czerwone, czy nie? Jak zasugerowano powyżej, porównania bitmap działają, Selenium, ale moim głównym celem nie byłoby przesadne testowanie GUI, ale raczej przetestowanie logiki, która pomoże stworzyć interfejs użytkownika, a następnie skup się na tym, która część interfejsu użytkownika psuje się lub jest podejrzana i skupi się na kilku testach tam.
źródło
Możesz użyć JFCUnit do przetestowania swojego GUI, ale grafika może być trudniejsza. Kilka razy zrobiłem migawki mojego GUI i automatycznie porównałem go z poprzednią wersją. Chociaż nie zapewnia to rzeczywistego testu, ostrzega, jeśli automatyczna kompilacja nie przyniesie oczekiwanych wyników.
źródło
Z twojego pytania wyciągam wniosek, że szukasz zautomatyzowanego sposobu szczegółowego przetestowania zachowania GUI, podany przykład to sprawdzenie, czy krzywa jest rzeczywiście narysowana poprawnie.
Struktury testów jednostkowych umożliwiają przeprowadzanie testów automatycznych, ale myślę, że rodzaj testów, które chcesz wykonać, to skomplikowane testy integracyjne, które weryfikują prawidłowe zachowanie wielu klas, w tym klas z zestawu narzędzi / biblioteki GUI, nie powinien chcieć testować.
Twoje opcje zależą w dużej mierze od używanych platform / zestawów narzędzi / frameworków: na przykład aplikacja używająca Qt jako struktury GUI może używać Squish do automatyzacji swoich testów. Weryfikujesz wyniki swoich testów raz, a kolejne automatycznie wykonywane testy porównują wyniki z wynikami zweryfikowanymi.
źródło
Okno Licker dla Swing & Ajax
źródło
Moje podejście do testowania GUI ewoluuje, podobnie jak konsensus branżowy. Myślę jednak, że zaczyna się pojawiać kilka kluczowych technik.
Używam jednej lub więcej z tych technik, w zależności od sytuacji (np. Jaki to rodzaj GUI, jak szybko należy go zbudować, kim będzie użytkownik końcowy itp.).
Testowanie ręczne. Zawsze masz uruchomiony GUI podczas pracy nad kodem i upewnij się, że jest zsynchronizowany z kodem. Ręcznie testujesz i ponownie testujesz część, nad którą pracujesz, podczas pracy nad nią, przełączając się między kodem a uruchomioną aplikacją. Za każdym razem, gdy wykonujesz jakąś znaczącą pracę, poddajesz cały ekran lub obszar aplikacji całościowy test, aby upewnić się, że nie ma regresji.
Testów jednostkowych. Piszesz testy dla funkcji lub małych jednostek zachowania GUI. Na przykład wykresy mogą wymagać obliczenia różnych odcieni koloru w oparciu o kolor „bazowy”. Możesz wyodrębnić to obliczenie do funkcji i napisać dla niej test jednostkowy. Możesz wyszukać logikę taką jak ta w GUI (zwłaszcza logikę wielokrotnego użytku) i wyodrębnić ją do dyskretnych funkcji, które można łatwiej przetestować jednostkowo. W ten sposób można wyodrębnić i przetestować nawet złożone zachowanie - na przykład sekwencję kroków w kreatorze można wyodrębnić do funkcji, a test jednostkowy może zweryfikować, czy po wprowadzeniu danych wejściowych zwracany jest prawidłowy krok.
Eksplorator komponentów. Tworzysz ekran „eksploratora”, którego jedyną rolą jest pokazanie każdego z komponentów wielokrotnego użytku, które tworzą twój GUI. Ten ekran umożliwia szybkie i łatwe wizualne sprawdzenie, czy każdy element ma właściwy wygląd i styl. Eksplorator komponentów jest bardziej wydajny niż ręczne przeglądanie całej aplikacji, ponieważ A) musisz zweryfikować każdy komponent tylko raz i B) nie musisz wchodzić w głąb aplikacji, aby zobaczyć komponent, możesz po prostu wyświetlić i sprawdź to natychmiast.
Testowanie automatyczne. Piszesz test, który współdziała z ekranem lub komponentem, symulując kliknięcia myszą, wprowadzanie danych itp., Zapewniając, że aplikacja działa poprawnie przy tych manipulacjach. Może to być przydatne jako dodatkowy test zapasowy, aby wychwycić potencjalne błędy, które mogą zostać pominięte w innych testach. Zwykle rezerwuję testowanie automatyzacji dla tych części GUI, które są najbardziej podatne na uszkodzenia i / lub są bardzo krytyczne. Części, w przypadku których chcę jak najwcześniej wiedzieć, czy coś się zepsuło. Może to obejmować bardzo złożone komponenty interaktywne, które są podatne na uszkodzenia lub ważne ekrany główne.
Testowanie różnic / migawek. Piszesz test, który po prostu przechwytuje dane wyjściowe jako zrzut ekranu lub jako kod HTML i porównuje je z poprzednim wynikiem. W ten sposób jesteś powiadamiany o każdej zmianie wyniku. Testy różnicowe mogą być przydatne, jeśli wizualny aspekt GUI jest złożony i / lub podlega zmianom. W takim przypadku potrzebujesz szybkiej i wizualnej informacji zwrotnej na temat wpływu danej zmiany na GUI jako całość.
Zamiast ciężko używać każdego możliwego rodzaju testu, wolę wybierać technikę testowania w oparciu o rodzaj rzeczy, nad którą pracuję. Więc w jednym przypadku wyodrębnię prostą funkcję i przetestuję ją jednostkowo, ale w innym przypadku dodam komponent do eksploratora komponentów itd. To zależy od sytuacji.
Nie znalazłem pokrycia kodu jako bardzo użytecznego wskaźnika, ale inni mogli znaleźć dla niego zastosowanie.
Myślę, że pierwszą miarą jest liczba i powaga błędów. Twoim głównym priorytetem jest prawdopodobnie posiadanie aplikacji, która działa poprawnie. Jeśli aplikacja działa poprawnie, powinno być niewiele lub żadnych błędów. Jeśli jest wiele lub poważnych błędów, przypuszczalnie albo nie testujesz, albo twoje testy nie są skuteczne.
Oprócz ograniczania błędów istnieją inne środki, takie jak wydajność, użyteczność, dostępność, łatwość konserwacji, rozszerzalność itp. Będą się one różnić w zależności od rodzaju aplikacji, którą tworzysz, firmy, użytkownika końcowego itp.
Wszystko to jest oparte na moim osobistym doświadczeniu i badaniach, a także świetnym artykule na temat testów interfejsu użytkownika autorstwa Ham Vocke .
źródło
Z tego co wiem, jest to dość skomplikowane i naprawdę zależy od języka - wiele języków ma swój własny sposób testowania GUI, ale jeśli naprawdę potrzebujesz przetestować GUI (w przeciwieństwie do interakcji model / gui), często musisz symulować klikanie przycisków przez rzeczywistego użytkownika. Na przykład framework SWT używany w Eclipse zapewnia SWTBot , o JFCUnit już wspomniano, Mozilla ma swój własny sposób na symulowanie tego w XUL (iz tego, co czytałem na ich blogach, testy te wydają się dość kruche).
Czasami musisz zrobić zrzut ekranu i przetestować renderowanie w pikselach (uważam, że Mozilla robi to, aby sprawdzić poprawnie renderowane strony) - wymaga to dłuższej konfiguracji, ale może być tym, czego potrzebujesz do wykresów. W ten sposób, gdy aktualizujesz kod i test się kończy, musisz ręcznie sprawdzić obraz, czy błąd był prawdziwy, lub ulepszyłeś kod renderujący wykres, aby generował ładniejsze wykresy i musisz zaktualizować zrzuty ekranu.
źródło
Jeśli używasz Swing, FEST-Swing jest przydatny do sterowania GUI i testowania asercji. Ułatwia to testowanie takich rzeczy, jak „jeśli kliknę przycisk A, powinno zostać wyświetlone okno dialogowe B” lub „jeśli wybiorę opcję 2 z listy rozwijanej, wszystkie pola wyboru powinny zostać odznaczone” .
Scenariusz wykresu, o którym wspomniałeś, nie jest łatwy do przetestowania. Całkiem łatwo jest uzyskać pokrycie kodu dla komponentów GUI, po prostu tworząc je i wyświetlając (i być może sterując nimi za pomocą FEST). Jednak tworzenie znaczących stwierdzeń jest trudną częścią (a pokrycie kodu bez znaczących twierdzeń jest ćwiczeniem w oszukiwaniu samego siebie). Jak sprawdzić, czy wykres nie był odwrócony do góry nogami lub zbyt mały?
Myślę, że musisz po prostu zaakceptować, że niektórych aspektów GUI nie można skutecznie przetestować za pomocą automatycznych testów jednostkowych i że będziesz musiał przetestować je w inny sposób.
źródło
Twoim zadaniem nie jest testowanie biblioteki GUI. Możesz więc uniknąć odpowiedzialności za sprawdzenie, co jest faktycznie narysowane na ekranie, i zamiast tego sprawdzić właściwości widżetów, ufając bibliotece, że dokładnie reprezentują to, co jest rysowane.
źródło