Testing

Sztuczna inteligencja pozwoliła pominąć kilkanaście tysięcy test case’ów. Uczenie maszynowe w praktyce

klawiatura na biurku

Ericsson kojarzy się z telefonami komórkowymi sprzed ery smartfonów. W rzeczywistości jest to firma, która działa w sektorze komunikacyjnym od prawie 150 lat, dzisiaj budująca i obsługująca sieci mobilne. Z naszych produktów korzystają miliardy ludzi na całym świecie, choć nie zawsze wiedzą, kto je wyprodukował. 

Klientami dla Ericssona są operatorzy sieci, a nie użytkownicy telefonów. Szukając sposobów na optymalizację pracy, korzystamy z innowacyjnych narzędzi takich jak sztuczna inteligencja. Poniżej opisuję to, jak wykorzystujemy uczenie maszynowe w praktyce.     

Pracuję w obszarze GSM, czyli pierwszej spopularyzowanej technologii komórkowej, rozwijanej od początku lat 90. Sieć 2G nie tylko zapewnia zasięg słabo zurbanizowanym obszarom świata, ale także w centrach wielkich miast, gdzie nadaje równolegle do 4G oraz 5G, żeby zapewnić działanie bankomatom, terminalom płatniczym czy nawet połączeniom głosowym, gdy wyższe technologie nie są w stanie ich obsłużyć. 

Praca z tak dojrzałym produktem ma swoją specyfikę. Zakupiło i wdrożyło go wielu klientów. Codziennie obsługuje on miliardy użytkowników, co oznacza, że stabilność działania jest krytycznie ważna. Nie możemy pozwolić sobie na błędy, które mogłyby skutkować odcięciem połowy kraju od dostępu do sieci, a w konsekwencji dostępu do telefonów alarmowych czy gotówki.

Rozwój produktu, a zwłaszcza dużych funkcjonalności, diametralnie wpływających na jego działanie, nie jest już tak dynamiczny, jak dekadę temu (choć może nie powinienem tego pisać, biorąc pod uwagę to, co akurat szykujemy do wypuszczenia). Większość ludzi została przerzucona do wyższych technologii, które są na innym etapie rozwoju. Stosunkowo niewielkie zasoby ludzkie (porównując z sytuacją choćby sprzed pięciu lat) oznaczają, że dostarczeń kodu jest mniej. Nie zmienia to jednak faktu, że każde z nich trzeba jak najdokładniej przetestować przed dostarczeniem kolejnego kawałka funkcjonalności.

Dostarczanie kodu

Zespoły zachęcane są do sukcesywnego dostarczania kodu. Nikomu nie jest jednak na rękę masowe dostarczanie, które nazywam big bang, w piątek po południu. Zbyt duża liczba „zakolejkowanego” kodu do testu na ograniczonej liczbie serwerów oznacza, że będą wykonywały się długo. A każde z nich potencjalnie zawiera krytyczny błąd, który może skończyć się niepowodzeniem dla kolejnych w sekwencji. 

Dlatego kolejne dostawy kodu spływają sukcesywnie przez cały tydzień. Z reguły obejmują zmiany w pojedynczych blokach lub grupach bloków kodu, a nie całe gotowe funkcjonalności, dotykające wielu obszarów działania centrali. Podczas dostarczania, deweloper powinien oznaczyć, na jakie obszary miał wpływ. Czy zmiany dotyczyły zarządzania komórkami sieci, zestawianiem połączeń głosowych, ruchu pakietowego, a może ograniczały się jedynie do dokumentacji. To tylko kilka przykładów tzw. Impact Area.

Typowa kampania testowa

W tym miejscu warto wspomnieć, jak wygląda kampania testowa. Zespoły deweloperskie przed dostarczeniem wykonują testy funkcjonalne nowego kodu. Natomiast po dostarczeniu wykonują się automatyczne test suity, utrzymywane przez organizację Continous Integration (CI). 

Testy są podzielone na kilka etapów, nazywanych promotion level. Pierwszy mówi o tym, czy kod w ogóle się kompiluje, czy unit testy przechodzą. Następnie sprawdzane są najbardziej podstawowe funkcjonalności w grupie testów nazywanej First Feedback. To jest dopiero pierwszy promotion level, który daje informację czy software nadaje się do ładowania na centrale w laboratorium.

Drugi promotion level (PL2) zaczyna się od sprawdzania, czy stare funkcjonalności (Legacy) działają na nowym kodzie. Następnie uruchamiane są: krótki Stability Test oraz pakiet negatywnych testów (Robustness), który sprawdza odporność oprogramowania na zdarzenia zaburzające działanie centrali.

Dopiero tak przetestowany software możemy uznać za stabilny. W teorii mógłby zostać posłany do klientów, jednak w praktyce jest to dopiero kwalifikacja do bardziej długotrwałych i skomplikowanych testów pogrupowanych w kolejne dwa promotion levele. Tam testowane jest zachowanie centrali pod dużym obciążeniem, długotrwałe stability, ze sprawdzeniem charakterystyk. Testowane jest także zachowanie bez symulatorów, gdzie prawdziwe jest wszystko od telefonu komórkowego po sieć szkieletową. 

Optymalizacja i szukanie oszczędności

Cała weryfikacja po dostarczeniu to długotrwały i kosztowny proces, ale Ericssonowi zależy na jakości produktu i zadowoleniu klientów. Stąd przez długie lata firma poświęcała temu bardzo dużo uwagi.

Długo i dokładnie nie znaczy jednak, że nie można by lepiej. Jeszcze kilkanaście lat temu kompilacja z testami jednostkowymi i przygotowanie działającego środowiska testowego trwały dwa dni. Potem przeprowadzane ręcznie testy zajmowały kolejne dni. W tamtych czasach proces dostarczania wyglądał jednak inaczej, odbywał się w większych porcjach, co po części wynikało z pracy w metodyce waterfall. W tamtych czasach testem zajmowało się wiele wyspecjalizowanych zespołów z kilku krajów.

Późniejsze przejście na metodyki zwinne (Agile) sprawiło, że dostarczenia kodu stały się częstsze. Testerzy w większości trafili do zespołów deweloperskich. Testowanie musiało stać się szybsze i bardziej efektywne. Jak już pisałem wcześniej, dostarczanie kodu odbywa się na bieżąco, a nie w zbiorczych pakietach. W takim razie dostarczeń jest sporo. Dzięki podziałowi na promotion levele nie trzeba wykonywać całego zakresu testów na każdym dostarczeniu. Wystarczy osiągnąć PL1, żeby potwierdzić, iż kod nie zawiera krytycznych błędów w podstawowych funkcjonalnościach. A jeśli błąd się znajdzie, przynajmniej łatwo wskazać, co zawiniło i szybko dostarczyć poprawkę lub wycofać wadliwą zmianę.

Brak konieczności uruchamiania testów wyższego poziomu, trwających po kilka-kilkadziesiąt godzin, pozwala na znaczne oszczędności czasu i zasobów. Uruchamianie zakresu PL2 tylko na wybranych, stabilnych dostarczeniach okazało się optymalne pod względem poświęconego czasu i znajdowanych błędów. W weekendy, kiedy nowy kod nie spływa, środowiska testowe mogą poświęcić czas na dokładne sprawdzenie tego dostarczenia, które zostało wybrane spośród tych, które osiągnęły PL2 w danym tygodniu. 

Używanie testów automatycznych optymalizowanych pod kątem czasu trwania, potrzebnych zasobów oraz możliwości zrównoleglania przyniosło wymierne korzyści. Nie tylko zmniejszyła się ilość sprzętu potrzebna do wykonania testów, to jeszcze może on pracować przez całą dobę. Mimo wszystko test suity z poziomu PL1 muszą być uruchamiane za każdym razem. Samych test case’ów Legacy i Regression powstało ponad 200 i choćby wykonywały się błyskawicznie, to ich liczba sprawiała, że na werdykt trzeba było czekać kilka godzin. Widać w tym pole do dalszej optymalizacji.

Uczenie maszynowe w praktyce

Na pomysł jak zoptymalizować czas wykonywania cyklu testów wpadł jeden z członków zespołu zajmującego się utrzymaniem testów automatycznych. Postanowił wykorzystać uczenie maszynowe, które dzięki zebranej historii wykonywanych test case’ów, przestanie wykonywać te z nich, które zostaną uznane za nieprzydatne do oceny jakości nowego kodu.

Na początek, wykorzystując używaną przez developerów Impact Area, należało zmapować test case’y na testowane obszary kodu i funkcjonalności. To pozwalało od razu wykluczać niektóre z test case’y podczas testowania zupełnie niezwiązanego z nimi dostarczenia. Zarówno pominięcie test case’a, jak i jego zakończenie sukcesem lub porażką (spowodowaną błędem), było zbierane w statystykach służących do uczenia sztucznej inteligencji.

Nadrzędnym celem przeprowadzania testów jest znajdowanie błędów. Powtarzanie w kółko testów, które kończą się sukcesem, może zwiększać przekonanie o dobrej jakości kodu, jednak na dłuższą metę jest to marnowanie czasu i zasobów. Algorytm powinien uczyć się pomijać taki test. Jednak najważniejsze, żeby nie pomijać testów, które akurat mogły znaleźć błąd. Wyważenie obu tych celów nie jest sprawą trywialną i stąd zastosowanie sztucznej inteligencji zamiast prostego automatu, który test wykona lub pominie na podstawie odgórnie narzuconych założeń.

W uczeniu maszynowym wykorzystywane są parametry takie jak:

  • ranking podobieństwa, który określa dopasowanie test case’a do dostarczanego kodu (tu ważne jest przygotowane wcześniej mapowanie wszystkich test case’ów na Impact Area). Im wyżej w rankingu, tym większe prawdopodobieństwo wybrania test case’a.
  • wskaźnik niepowodzeń, czyli liczba znalezionych błędów pośród wszystkich wykonań test case’a. Test, który zwykle się udaje, dostaje niższą wagę.
  • waga dostarczenia będąca sumą dostarczeń w poszczególnych blokach kodu, od ostatniego dostarczenia przetestowanego przez dany test case. Im więcej edytowanych bloków kodu oraz im więcej czasu minęło, odkąd były pokrywane danym test case’em, tym większa waga test case’a.
  • liczba powtórzeń od ostatniego sukcesu. Jeśli test raz za razem kończy się porażką, to przed ponownym wykonaniem należałoby w końcu poprawić błędy w kodzie lub przyjrzeć się czy procedura testu nie jest błędna.

To tylko ogólny opis. W sumie powstało ponad 40 liczbowych parametrów opisujących każdy z test case’ów. Maszyna potrafi zapamiętać całą historię powtórzeń testu. Im jest ich więcej, tym dokładniejsze może być przewidywanie czy test case znajdzie błąd, czy można go pominąć.

Co istotne, parametry można w każdej chwili wyzerować i zmusić maszynę do ponownej nauki. Na przykład w sytuacji, gdyby w istotny sposób zmienił się sposób działania centrali albo często zgłaszane były błędy, które powinny zostać wykryte w pomijanych testach.

Żeby jednak nie zostawiać pełni kontroli w rękach sztucznej inteligencji, a także, żeby zapewnić jej dodatkowe dane do uczenia się, co jakiś czas wykonywany jest pełen zakres testów. W ten sposób można być pewnym, że każdy test case, nawet taki notorycznie pomijany, ma regularnie odświeżane statystyki. A potencjalne błędy nie przedostają się przez okrojoną kampanię testową.

Czy sztuczna inteligencja działa

Przez ponad dwa lata odkąd uczenie maszynowe zostało zaprzęgnięte do działania, zredukowało liczbę wykonanych testów średnio o 56%. Największe oszczędności zanotowano w grupie First Feedback, gdzie zostało pominięte aż 65% testów w całym badanym okresie.

Skalę oszczędności czasu i zasobów lepiej obrazuje bezwzględna liczba prawie 19 000 pominiętych test case’ów. Trzy grupy testów, które są obsługiwane przez sztuczną inteligencję, zamiast po kilka godzin wykonują się średnio ok. 90 minut. W razie wykrycia błędu w dostarczeniu pozwala to często na jego naprawę jeszcze tego samego dnia.

Pomimo tak drastycznego okrojenia zakresu testów, praktyka pokazuje, że znajdowanych jest ok. 95% błędów, które powinny być wykryte na tym właśnie etapie testowania. Optymalizacja okazała się więc wielkim sukcesem.

Potencjalne korzyści z AI w innych zastosowaniach

W erze ChatGPT zastosowania dla sztucznej inteligencji wydają się nieograniczone, a temat jest gorący i omawiany na tysiące sposobów. Osobiście nie uważam, żeby AI mogła w pełni zastąpić doświadczonego testera w zaprojektowaniu i przeprowadzeniu całej kampanii testowej. Jeszcze nie teraz. Jednak pisanie testów jednostkowych zdecydowanie powinno być w jej zasięgu. Tak jak ponoć radzi już sobie z pisaniem prostych programów.

Jak wspomniałem, uczenie maszynowe potrzebuje danych wejściowych. Im więcej, tym lepiej. Trzeba wiedzieć, czego się szuka (co jest wyjściem) i jak sparametryzować dane wejściowe. A wtedy obróbka danych jest znacznie bardziej efektywna niż ręczne przeglądanie logów nawet przez liczny zespół. Same dane w obecnych czasach nie są problemem. Zbieranie informacji i handel nimi to rynek sam w sobie. Więc nawet początkująca firma, jeśli dysponuje kapitałem, może pozyskać czy to dane potrzebne do rozwoju produktu, czy informacje, czy o potencjalnych klientach.

W przypadku mojego obszaru taka sztuczna inteligencja mogłaby pomóc tworzyć model symulowanego trafficu w sieci. To jest coś, co i tak robimy, zwykle w procesie przeglądania danych od operatorów sieci przez naszych ekspertów, następnie licznych spotkań i dyskusji decyzyjnych osób. Od uzyskania zgody od klienta na dostarczenie logów do powstania działającego modelu mija więc dużo czasu. 

Tymczasem na podstawie logów zbieranych przez klientów można by wytrenować sztuczną inteligencję, która zwróciłaby uśredniony model zachowania użytkownika sieci. Czy korzysta z połączeń głosowych, czy transferu danych, jak długo trwają połączenia/transfery, jaka jest mobilność w sieci, czyli jak często użytkownik zmienia komórkę, w której się znajduje. Posiadając aktualne modele, moglibyśmy lepiej testować rzeczywiste zachowanie sieci i szukać problemów, które mają większe szanse wystąpić u naszych klientów. I moglibyśmy wykorzystać dane z całego świata. Dla przykładu model, który powstał kilkanaście lat temu, brał pod uwagę dane z pojedynczego miasta. 

Ruch w sieci 2G znacznie się zmienił przez te 30 lat istnienia. Rozmów głosowych najpierw było coraz mniej, a na znaczeniu zyskiwał internet, potem ruch pakietowy w coraz większym stopniu przechodził do wyższych technologii np. LTE, pozostawiając GSM do obsługi głosu. A obecnie to znowu “pakietówka” zyskuje na znaczeniu, gdyż bankomaty, terminale płatnicze i różnego rodzaju czujniki i kontrolery IoT mogą swobodnie korzystać z tanich, energooszczędnych nadajników GSM, zwykle nie potrzebując przepustowości oferowanych przez nowsze technologie.

Jeśli się zastanowić, modelowanie zachowań użytkowników mają wręcz nieograniczone zastosowania. Nawet śledzenie czynności wykonywanych podczas robienia zakupów czy przeglądania witryny internetowej da się wykorzystać. Czy to do realistyczniejszego testowania, czy optymalizacji produktu albo usługi. A analizę zachowań na podstawie tysięcy próbek, lepiej wykona sztuczna inteligencja niż niewielki zespół ludzi. Mamy więc efekt skali – mała firma z licznie odwiedzaną aplikacją webową, efektywniej spędzi czas na stworzeniu sztucznej inteligencji niż żmudnej obróbce logów. Zresztą ostatnie miesiące pokazały, że samo stworzenie dobrze działającego, uniwersalnego silnika AI może przykuć uwagę klientów, inwestorów czy mediów z całego świata. I warto iść w tę stronę.

Zdjęcie główne artykułu pochodzi z unsplash.com.

Verification Manager w Ericsson

Z Ericssonem związany od 2010 r., kiedy jeszcze studiował na AGH. Sporo czasu spędził w szwedzkim laboratorium, wykonując testy integracyjne na prawdziwych centralach telefonicznych. Później jako tester w zespole XFT znalazł się bliżej kodu i pojedynczych funkcjonalności. Obecnie jako Verification Manager nadzoruje strategię testu i środowiska testowe w obszarze GSM. Z zamiłowania bardziej sprzętowiec niż programista. Interesuje się i gromadzi przeróżną elektronikę użytkową. Od systemów nagłośnienia, poprzez podzespoły komputerowe aż po gadżety i sprzęt IoT, o który sukcesywnie powiększa swoją sieć domową.

Podobne artykuły