wtorek, 30 czerwca 2009

migawka moich zainteresowań

Tak sobie oglądałem nagranie z konferencji w Google na YouTubie
(www.youtube.com/watch?v=ifmZSC8ca6Q) i tą drogą odkryłem zespół Nine Inch Nails. Gorąco polecam. Oto link do aplikacji, za pomocą której można śledzić na bierząco wiadomości wysyłane przez fanów zespołu: http://access.nin.com/
Wykorzystują plugin Google Earth do przeglądarki internetowej, żeby pokazać, skąd pochodzi wiadomość i do różnych innych rzeczy.
To link do strony domowej zespołu: http://www.nin.com/
Rozdają swoją muzykę za darmo! Ściągnąłem w formacie .flac, odtwarzam Winampem i jestem bardzo zadowolony z jakości.

niedziela, 14 czerwca 2009

Bootstrapping automatycznego testowania GUI

Odpoczywam sobie właśnie w Polsce po sesji i myślę o tym, jak można by zabrać się za napisanie zestawu automatycznych testów do mojego systemu GUI. Chodzi konkretnie o to, żeby kod widżetów w trybie debug mógł sprawdzić, czy nadal jest rysowane to, co trzeba. Takie sprawdzanie byłoby bardzo przydatne, a wręcz niezbędne zwłaszcza wtedy, gdy zmieniane są szczegóły implementacji niskopoziomowych komponentów. Wcześniej, gdy struktura GUI ulegała dużym zmianom, robienie testów wymagałoby ciągłego ich zmieniania. Teraz problem nieistnienia zestawów testów daje się we znaki, a zmiany strukturalne GUI nie są znaczące.

Mimo to pisanie ręcznie testów sprawdzających dokładny wygląd GUI nie wydaje się najlepszym pomysłem. Jest to ogromny wysiłek, który mógłby być przeznaczony na coś dużo bardziej produktywnego. Ponadto koszt utrzymania takiego kodu jest ogromny przy najdrobniejszych zmianach wprowadzonych do podstawowych komponentów.

Dużo lepszym wyjściem jest pisanie testów sprawdzających po kilka najbardziej narażonych na niezgodności punktów - rogów, czubków itd. To jest do przyjęcia, jeśli chodzi o ilość potrzebnego wysiłku, jednak niedokładność jest oczywista. Taki kod nie zawsze wykryje, że coś się zmieniło, a o to przecież chodzi w automatycznym testowaniu.

Niezależnie od tego, co obejmują napisane testy, są one narażone na błędy w samych testach. Są możliwe do wykrycia i naprawienia, ale jednak dokładają roboty.

Wpadłem więc na pomysł, aby napisać te wyrywkowe testy, uruchomić je, sprawdzić wzrokowo, czy rysuje się to, co trzeba i zapisać obrazki z wizerunkami widżetów do plików.

Później automatyczny kod testujący mógłby sprawdzać zgodność tego, co się wyrysuje (za pomocą króciutkiego kodu) z tymi obrazkami. W ten sposób, praktycznie nie pisząc kodu do poszczególnych przypadków mam sprawdzanie dokładności rysowania GUI co do piksela, sprawdzanie zmian i automatyczne generowanie testów. Tak, mam automatyczne generowanie testów, bo po każdej poprawce będę mógł wywołać funkcję 'generate_tests', która utworzy mi obrazki ze wszystkimi widżetami. Nie będę musiał zmieniać setek linii kodu, najwyżej kilkanaście, ale tylko wtedy, gdy poprawka będzie usuwała błąd ujęty w zestawie napisanych testów. Ponadto testy obrazkowe są niewrażliwe na błędy w kodzie testującym, zamiast kodu testującego jest bowiem obrazek, skontrolowany wzrokowo wcześniej, podczas tworzenia widżeta (lub późniejszego naprawiania usterki).

Przedstawione rozwiązanie kusi swoją prostotą ale trzeba rozważyć jeszcze kilka rzeczy. Najważniejsze: ogólność. Dla wielu trybów rysowania może być wiele obrazków, które muszą zostać sprawdzone, żeby było pewne, że naprawdę wszystko jest tak, jak trzeba. Jako tryb rysowania można podać rysowanie z wygładzaniem krawędzi lub bez. To stawia pod znakiem zapytania całą metodę, ponieważ rozmiar tych obrazków na dysku może być potężny. Po przyjęciu stosowania odpowiednich, prostych tekstur i kompresowania do formatu PNG będzie znacznie mniejszy, jednak nadal będzie zależny od iloczynu wszystkich sposobów rysowania dla różnych trybów. Rozwiązaniem mogłoby być tworzenie obrazków tylko dla niektórych trybów przy cichym założeniu, że dla wszystkich innych możliwości wszystko będzie w porządku bo są już przetestowane we własnym podstawowym zestawie testów. Można też wybierać różne konfiguracje dla różnych widżetów.

Inny problem: Można zapytać, czy warto utrzymywać zestaw ręcznie napisanych testów dla danego komponentu po upewnieniu się, że rysuje się co do piksela. Napisane testy przechowują wiedzę o tym, co zostało przetestowane dokładnie, a co tylko wizualnie. Co ważniejsze są też kodem, który można łatwo przerobić i wykorzystać do przetestowania po poprawkach konkretnych wartości na rysunku komponentu. Testowanie po zmianach jest niezbędne, więc wydaje się oczywiste, że taki kod powinien być zachowany. Utrzymanie go nastręcza jednak dodatkowego wysiłku. Można go zachować i nie uruchamiać, żeby nie robić sobie kłopotów, jednak wtedy nie będzie gwarancji, że działa tak, jak należy. Wobec takiego stanu rzeczy najlepsze wydaje się zachowanie go i uruchamianie na żądanie wtedy, kiedy trzeba upewnić się, że nadal działa. To rozwiązanie problemu nadal nie jest jednak idealne, bo przy każdej zmianie będzie tworzyć pokusę, żeby nie działający kod testujący po prostu zignorować i wyrzucić, a test oprzeć na sprawdzaniu obrazka.

Jeszcze jedno pytanie wymaga odpowiedzi: Czy traktować obrazki jako testy poprawności, czy tylko jako testy zmian w wyświetlaniu, a do testowania poprawności utrzymywać testy napisane ręcznie. Sugestie mile widziane.

W tym poście trzeba jeszcze wyjaśnić skąd "bootstrapping" w tytule. Wikipedia wyjaśnia, co oznacza to słowo, a ja tylko dodam, że tutaj zostało użyte przez analogię do bootstrappingu kompilatorów. Tak, jak kompilator podzbioru reguł języka X zostaje użyty do napisania kompilatora języka X, tak częściowo przetestowane GUI Y zostaje użyte do wytworzenia pełnych testów do GUI Y.