SonarQube, statyczna analiza i wysoka jakość kodu

SonarQube, statyczna analiza i wysoka jakość kodu

O kod trzeba dbać – z tym raczej wszyscy się zgodzimy. Wysoka jakość kodu ma nam pomóc między innymi w rozwoju i utrzymaniu projektów. Oczywiście wspomniana wysoka jakość kodu nie bierze się z niczego. Jest to efekt codziennej pracy i dbania o każdy szczegół. Na rynku istnieją narzędzia, które umożliwiają monitorowanie jakości kodu na bieżąco. Jeżeli nie chcesz wpaść w dług technologiczny na pewno warto się z nimi zapoznać!

SonarQube

Jednym z tych narzędzi jest właśnie statyczny analizator kodu SonarQube. Przy pomocy SonarQube możemy dokonać statycznej analizy kodu naszego projektu (wspierane języki to między innymi: C#, Java, JavaScript, PHP, TypeScript) i otrzymać zgrabny raport na temat stanu/jakości kodu. Informacje jakie dostarcza nam SonarQube to między innymi:

  • Bugs – kod, który może zachować się inaczej niż moglibyśmy się tego spodziewać ;).
  • Code Smells – wszystkie “zapaszki” kodu, które obniżają wskaźnik “utrzymywalności” (maintainability) projektu.
  • Vulnerabilities – potencjalne miejsca, gdzie nasz kod może być podatny na jakiś atak.
  • Test coverage – pokrycie kodu testami.
  • Duplications – kod, który jest zduplikowany.
  • Complexity – złożoność cyklomatyczna kodu.

Wszystkie te dane cząstkowe składają się na ogólny wskaźnik stanu jakości kodu. Co ważne – SonarQube wiąże wyżej wymienione dane techniczne z informacjami biznesowymi. Oznacza to, że każdy problem znaleziony podczas statycznej analizy kodu ma swoje odzwierciedlenie w postaci przykładowo zwiększającego się długu technologicznego przeliczanego na minuty, godziny, dni. Na pierwszy rzut oka może wydawać się to fajną funkcjonalnością, bo narzędzie staje się użyteczne na poziomie stanowisk kierowniczych projektu jednak, czy faktycznie? O tym później 🙂

Na ten moment stańmy na tym, że jesteśmy w stanie otrzymać dużą dawkę istotnych informacji o jakości naszego kodu.

Ile kosztuje wprowadzenie SonarQube do projektu?

Musimy zwrócić uwagę na dwie “metryki”: czas i pieniądze.

Zacznijmy od końca, czyli kwestia pieniędzy. Ogólnie SonarQube jest narzędziem open source, więc możemy korzystać z niego za darmo. Jednak, gdy spojrzeć głębiej to do końca SonarQube darmowy nie jest. Spójrzmy jak to wygląda na ten moment:

Jak widać samo narzędzie jest darmowe. Problem pojawia się przy wsparciu języków. Takie języki jak C#, Java, JavaScript, PHP, czy TypeScript są wspierane za darmo, dla reszty trzeba ponieść dość spory koszt. Tak, czy inaczej paczka języków dostępnych za darmo jest w mojej opinii dość spora.

Możemy przejść zatem do drugiej kwestii – czasu. Mam na myśli oczywiście czas, który trzeba poświęcić na konfigurację i uruchomienie SonarQube. Uruchomienie wszystkiego po raz pierwszy w życiu na lokalnej maszynie i przeprowadzenie pierwszej statycznej analizy kodu zajęło mi nie dłużej niż półtorej godziny, więc myślę, że nie jest źle (jak zawsze jakieś problemy musiały się po drodze pojawić). Kolejna konfiguracja powinna przebiec bez większych problemów i myślę, że można się z tym uporać w 5-10 minut.

Lokalna maszyna to jedno, a co z serwerami deweloperskimi/produkcyjnymi? Tutaj SonarQube również wychodzi na przeciw naszym oczekiwaniom. Mianowicie bez problemu możemy zintegrować SonarQube z większością dostępnych na rynku narzędzi Continous Integration (TeamCity, Bamboo, Jenkins..) oraz build systemów (MsBuild, Makefile, Ant, Maven..).

Wskaźniki, procenty, czas, dług technologiczny

Wspomniałem wcześniej, że SonarQube przedstawia w raportach znalezione problemy wraz z informacją o wzrastającym długu technologicznym przedstawionym w jednostce czasu. Wróćmy do tego na moment. Spójrzmy na przykładowy raport jeszcze raz:

W sekcji Code smells można zauważyć omawiany dług wynoszący 49dni. Oczywiście jest tutaj więcej ciekawych wskaźników – literki określające ogólną jakość kodu, czy procentowe pokrycie kodu testami.

No właśnie. Sporo wskaźników. Najlepiej, żeby wszystkie kółeczka były na zielono, wskaźniki procentowe na 100%, a dług technologiczny równy 0. Brzmi jak cel? Myślę, że tak. Jaki pojawia się problem? A no, jeżeli mamy zadany cel to będziemy dążyli do próby jego osiągnięcia.

W pewnym sensie jest to słuszne założenie, ale może być źle zrozumiane. O co mi chodzi? Moim zadaniem wdrażamy narzędzia typu SonarQube do projektu, aby nam służyło i pomagało, a nie po to, żeby troszczyć się tylko o jego wskaźniki. Prawda – obie te rzeczy nie wykluczają się, jednak trzeba mieć świadomość, że czasami nie warto robić czegoś TYLKO dla tego, że tak pokazuje SonarQube. Mam na myśli przykładowo nagły skok na pisanie testów, bo mamy mało % w test coverage. O jakości tych na szybko pisanych testów na potrzeby podniesienia wskaźnika możemy się domyślić. To samo dotyczy refaktoryzacji.

Cel osiągnięcia stanu wszystkich wskaźników na ich najlepszym poziomie nie jest zły sam w sobie, nie pozwólmy tylko, aby osiągnięcie tego celu odbyło się kosztem jakości wykonanych poprawek.

Co dalej?

SonarQube posiada bogatą bibliotekę pluginów. Warto zapoznać się z dostępnymi rozszerzeniami, aby maksymalnie zintegrować SonarQube z aktualnie wykorzystywanymi w projekcie narzędziami, a co za tym idzie, cały proces statycznej analizy kodu zautomatyzować.

Jednym z ciekawszych pluginów jest rozszerzenie umożliwiające integracje raportów SonarQube z GitHub Pull Requests. Jeżeli pracujemy w oparciu o pull requests analiza wykonana przed mergem przez SonarQube może być dodatkowym wyznacznikiem jakości kodu oprócz klasycznego, manualnego code review.

Kończąc

Tyle wstępnych informacji na ten SonarQube. Pracuję z nim na co dzień w pracy, ostatnio również postanowiłem skonfigurować lokalnie dla własnych projektów. Niedługo podzielę się informacjami na temat kroków, które musiałem wykonać, aby zainstalować SonarQube lokalnie – napotkałem na parę problemów, których rozwiązania nie znajdziecie w dokumentacji.

  • Grzegorz Dudek

    Fajne wprowadzenie 🙂

    Po stronie kosztów dodał bym jeszcze kwestię utrzymanie infrastruktury:
    – Nawet jeśli zdecydujemy się na darmową wersję SonarQube, to będziemy potrzebować serwer, na którym go zainstalujemy (on premise, cloud) + DB. Dobrze też, aby to nie był jeden serwer, jeśli chcemy zachować ciągłość w przypadku jakiejś awarii.
    – Analiza kodu jest czasochłonna, a więc wydłuża znacząco czas builda. Jeśli mamy build serwer w chmurze, przełoży się to na wyższe rachunki. Jeśli mamy build serwer on premise, możliwe, że potrzebować będziemy dodatkowe serwery pod agenty, aby zachować płynność.

    Po stronie zysków – odzyskanie części czasu poświęconego na pull requesty.
    Posiadając SonarQube, niektóre rzeczy są sprawdzane automatycznie, a programista / architekt może skupić się na rzeczach, których statyczna analiza nigdy nie wyłapie, czyli na przykład na sposobie rozwiązania danego problemu, czy wydajności.

    Dla BitbucketServer również istnieje plugin, który pokazuje jak zmieniają się nasze metryki wraz z pull requestem – https://marketplace.atlassian.com/plugins/ch.mibex.stash.sonar4stash/server/overview

    W przypadku Legacy Apps stan, w których wszystkie wskaźniki są na 100% jest w praktyce nieosiągalny 🙂
    Skupił bym się na obserwacji trendu i zadbał o to, aby wraz z przyrostem linii kodu dług technologiczny się nie zwiększał.

    • Adrian Bystrek

      Dzięki za trafne spostrzeżenia z Twojej strony 🙂