Dobre oprogramowanie wbudowane – know how tworzenia systemów embedded - Blog Solwit

Dobre oprogramowanie wbudowane – know how tworzenia systemów embedded

Autor: Piotr Strzałkowski, Embedded Domain Expert

Co to oznacza, że oprogramowanie wbudowane jest dobre? Zazwyczaj, z perspektywy product ownera, definicja dobrego oprogramowania wbudowanego będzie sprowadzała się do jak najlepszego dopasowania aplikacji do potrzeb klienta, minimalizacji błędów w kodzie i dostarczenia aplikacji na czas. Czy aby na pewno takie podejście jest słuszne?

Popularna definicja dobrego systemu embedded wg product ownera

Bez wątpienia, najważniejszą cechą oprogramowania jest zgodność jego działania z oczekiwaniami klienta, które są opisane przy pomocy wymagań funkcjonalnych i niefunkcjonalnych. Zarówno deweloperowi, jak i product ownerowi zależy na tym, żeby dany system miał wszystkie opisane funkcjonalności i działał jak najsprawniej — bez zawieszania się i luk w bezpieczeństwie.

Kolejną cechą dobrej aplikacji embedded, z punktu widzenia produkt ownera jest dostarczenie oprogramowania na czas. Jeśli nie wykonamy zlecenia w terminie, istnieje ryzyko, że wyprzedzi nas konkurencja albo klient nie będzie chciał kontynuować z nami współpracy. Wtedy cała nasza praca pójdzie na marne. Dlatego ważne jest, żeby jeszcze na etapie rozmów z klientem, przeprowadzić dokładną analizę i zebrać jak najwięcej danych, aby jak najtrafniej określić czas realizacji projektu i nie dopuścić do opóźnień.

Niezawodność oprogramowania to kolejna cecha, którą najczęściej usłyszymy, gdy zapytamy: co to znaczy, że aplikacja jest dobra. Im mniej błędów będzie zawierać, tym bardziej sprawne będzie oprogramowanie. Błędy w aplikacji to istotny problem. Ich reprodukcja, a następnie naprawa jest czasochłonna, a to wpływa na budżet projektu oraz ostateczny wizerunek produktu. Niemniej jednak minimalizacja błędów, to tylko jeden z elementów układanki zwanej jakością kodu i jak się okazuje, niekoniecznie najważniejszy.

Dobre oprogramowanie embedded z perspektywy product ownera: 

  1. Działa zgodnie z wymaganiami funkcjonalnymi i niefunkcjonalnymi.
  2. Ma minimalną ilość błędów.
  3. Jest dostarczone na czas.

Wyważenie tych trzech elementów jest, teoretycznie, złotym środkiem do stworzenia dobrego oprogramowania. Brzmi prosto, a jednak takie proste nie jest. Za chwilę dowiesz się, co tak naprawdę możesz zrobić, by tworzyć oprogramowanie dobrej jakości.

Oprogramowanie na czas

Zanim zaczniemy tworzyć oprogramowanie, należy zdefiniować, jakiej jakości i funkcjonalności aplikacji oczekuje od nas klient/właściciel biznesowy projektu. Tylko wtedy możemy określić potencjalne ryzyka oraz zasoby – nakład pracy, wielkość zespołu i czas.

Czas i budżet

Zdarza się, że zaproponowany przez nas czas realizacji nie odpowiada klientowi, a jednocześnie budżet projektu nie pozwala na zwiększenie zespołu. Wówczas, należy przeanalizować, z jakich funkcjonalności możemy zrezygnować, by zmieścić się w wyznaczonym przez klienta czasie i budżecie. Zaczyna się trudna droga do uzyskania kompromisu. Co ważne, takie estymaty są niezbędne, żeby zrealizować projekt.

Zdefiniowanie ryzyk

Kolejny aspekt, to zdefiniowanie ryzyk produktowych i projektowych, a później  ich cykliczne analizowanie. Minimalizowanie tych ryzyk to większa szansa na oddanie oprogramowania na czas.

Priorytetyzacja

Jeśli przeanalizujemy, które funkcjonalności są priorytetowe, a które mniej ważne, w początkowej fazie projektu, będziemy mogli lepiej zoptymalizować czas wykonania oprogramowania. Możemy zaoszczędzić czas lub przeciwnie – zdarza się, że analiza wykaże, że czas realizacji należy wydłużyć, jeśli zależy nam na zachowaniu odpowiedniego poziomu jakości aplikacji lub utrzymaniu wymaganych przez klienta funkcjonalności.

Architektura rozwiązania

Prace nad oprogramowaniem powinny rozpocząć się od precyzyjnego i szczegółowego scharakteryzowania jego działania. Tylko wtedy będzie można optymalizować jego wytworzenie. Podstawą dobrego opisu systemu są wymagania definiujące działanie oprogramowania, które dzielą się na funkcjonalne i niefunkcjonalne. Kolejnym krokiem jest architektura oprogramowania wynikająca z określonych wcześniej wymagań. Jeśli ten etap projektu, czyli definicja wymagań i tworzonej na ich podstawie architektury zostanie pominięty lub zaniedbany, konsekwencje dla projektu będą druzgocące.

Dlaczego? Ponieważ wymagania i architektura są fundamentem tworzenia oprogramowania. Niejasne i niepełne dane dadzą  deweloperom i testerom pole do własnych interpretacji. A mogą one być różne – raz prawidłowe, innym razem błędne i nie zawsze spójne z tym, jak powinien działać system.

Brak wymagań niefunkcjonalnych dotyczących: użyteczności, niezawodności, wydajności, dostępności, wsparcia, sposobu wdrożenia, skalowalności czy bezpieczeństwa wywołuje niejasności w zakresie działania systemu w tych aspektach. Lepiej mieć wąskie wymagania w każdym aspekcie oprogramowania niż wcale.

Testy wysokiego poziomu

Aby sprawdzić, czy wszystkie opisane funkcjonalności zostały zaimplementowane i działają zgodnie z założeniami należy przeprowadzić testy oprogramowania – typu funkcjonalnego i niefunkcjonalnego, w ramach testów wysokiego poziomu – systemowych i akceptacyjnych. Testy typu funkcjonalnego umożliwiają weryfikację poprawności i kompletności funkcjonalności, w tym funkcjonalności użytkowej. Z kolei testy niefunkcjonalne umożliwiają weryfikację zależności czasowych, zużycia zasobów, integralności i poufności.

Należy pamiętać, że oprogramowanie powinno spełniać jeszcze jedno wymaganie – testowalność. Przeważnie nikt nie chce poświęcić wytwarzaniu oprogramowania trzech miesięcy, a potem kolejnych sześciu lub więcej, by je testować. Z tego powodu, podczas tworzenia architektury oprogramowania, a nawet samego systemu, warto uwzględnić mechanizmy umożliwiające lub ułatwiające przeprowadzanie testów. Gdy już mamy zapewniony mechanizm nadzorujący funkcjonalności oprogramowania, możemy skupić się na redukcji zawartych w nim defektów innego typu.

Testy oprogramowania średniego i niskiego poziomu

W wyszukiwaniu kolejnych błędów wspomogą nas testy oprogramowania średniego i niskiego poziomu. Najbardziej efektywne będą takie testy, które mają najlepszy stosunek jakości do ceny. Zaliczamy do nich analizę statyczną kodu, asercje w kodzie oraz review kodu.

Dzięki analizie statycznej kodu możemy dopilnować standardów kodowania zdefiniowanych dla projektu, co poprawia analizowalność kodu. Dodatkowo możemy nadzorować wszelkie reguły logiczne, przepływy danych oraz martwy kod. To z kolei poprawia modularność, integralność i współdziałanie komponentów oprogramowania. Należy pamiętać, że analiza statyczna nie stanowi panaceum na wszystko, dlatego warto dodatkowo zastosować asercje i obsługę wyjątków w kodzie, tym samym zwiększając jego stabilność. To poprawi tolerancję na błędy i dostępność systemu.

W większych bardziej rozbudowanych projektach, gdzie nad oprogramowaniem pracuje wielu deweloperów, warto zastosować przegląd kodu, czyli tzw. review kodu, które wykonywane jest pod kątem architektury i działania systemu, a nie składni czy nazewnictwa (w tych przypadkach lepiej sprawdzają się narzędzia, a nie człowiek). Takie podejście umożliwia kontrolę nad poprawnością i pełnością implementacji kodu w stosunku do architektury i wymagań.

W przypadku bardziej zaawansowanych projektów lub projektów wymagających wysokiej jakości kodu warto wprowadzić dynamiczną analizę oprogramowania, czyli unit testy lub podejście TDD (test driven development). W przypadku TDD w pierwszej kolejności tworzymy unit test, a później kod. W kolejnym kroku naprzemiennie powstają unit testy z kodem wraz z rozbudową danej funkcjonalności. Chociaż to rozwiązanie doskonale dopełnia proces testowania kodu, jest droższe w porównaniu do poprzednich metod. Ponieważ stosujemy je w pierwszej fazie projektu, trzeba uwzględnić czas na napisanie i utrzymanie testów lub posiadać wykwalifikowanych w tej metodyce deweloperów. To poprawia modularność, reużywalność, testowalność, dojrzałość i obniża ilość błędów w testach wyższego poziomu.

Kolejnym etapem testów średniego poziomu są testy integracyjne software-software i software-hardware. Ten poziom testów, jako oddzielna czynność testowa, występuje zazwyczaj tylko w dużych projektach. W mniejszych ten etap jest pomijany lub integrowany z testami funkcjonalnymi, lub testami deweloperskimi podczas implementacji. Stosowanie tego typu testowania, umożliwia dodatkową kontrolę nad dostępnością systemu, odpornością na błędy czy współdziałaniem i współistnieniem, na przykład dwóch oprogramowań na jednej platformie.

Cechy, które wynikają z zastosowanych w projekcie testów i wpływają bezpośrednio na jakość oprogramowania:

Charakterystyki jakości oprogramowania według normy ISO/IEC 25010.

Nasza definicja dobrego oprogramowania wbudowanego

Analizując oba wykresy, można zauważyć, że wybór rodzaju testów oprogramowania w projekcie ma bezpośredni wpływ na jakość kodu, a ilość błędów jest tylko jednym z czynników jakościowych oprogramowania. Testujemy więc nie tylko po to, żeby zmniejszyć ilość błędów czy sprawdzić funkcjonalności, ale również, żeby podnieść całościową jakość oprogramowania. Jak widać, jakość aplikacji to bardziej złożone pojęcie.

Teraz możemy zaktualizować wcześniej omówione cechy dobrego oprogramowania.

Poniższy rysunek przedstawia cechy dobrego oprogramowania, na bazie naszych wieloletnich doświadczeń.

Tym, co sprawi, że nasze oprogramowanie wbudowane (oprogramowanie embedded) będzie dobre, są skrupulatnie i jasno opisane wymagania systemu i oprogramowania. Ważna jest także spójna architektura wyjaśniająca najważniejsze aspekty rozwiązań działania oprogramowania, które z kolei są niezbędne do wytworzenia aplikacji i jej testowania.

Na bazie zdefiniowanych cech jakościowych aplikacji, należy odpowiednio dobrać poziomy, typy i ilości testów, bo dzięki temu będziemy posiadać metryki opisujące jakość wytworzonego kodu i będziemy mogli określić, czy ta jakość spełnia założone wymagania.

Warto też pamiętać, że podczas każdego procesu wytwarzania oprogramowania najważniejsi są ludzie. Bez ich zaangażowania, nawet najlepsze rozwiązania zawiodą, dlatego zgrany zespół deweloperów i testerów to połowa sukcesu.

Jesteśmy Platynowym Partnerem ISTQB i zatrudniamy ponad 100 testerów z certyfikatami Advanced i Foundation.  Potrzebujesz dobrego oprogramowania wbudowanego?
Napisz do nas, a w wolnej chwili zajrzyj na stronę: oprogramowanie wbudowane (systemy embedded) i systemy safety-critical.

Najnowsze wpisy na blogu