2017. június 16.

Statikus kódanalízis Androidon

10 perc olvasási idő

Statikus kódanalízis Androidon

Szoftverfejlesztésben a hibák megelőzése kiemelt figyelmet érdemel. Minél később észlelsz egy hibát, annál költségesebb kijavítani. A legjobb az lenne, ha fordítód figyelmeztetne a rossz gyakorlatokra, lehetséges összeomlásra és ajánlásokat adna hogyan javíthatnál a kódodon. Ilyen segítséget nyújt neked a statikus kódanalízis.

Az egész úgy működik, hogy a kód futtatása nélkül ellenőrzöd a kódot. Legtöbb esetben vagy a forráskódon vagy annak egy formáján zajlik egy vizsgálat (például Java esetén, a bájtkódon). Az ellenőrzéseknek lehet célja egy konvenció betartása, komplexitás leszorítása vagy gyakori hibák elkerülése.

Lehetséges eszközök

Lint

Az Android fejlesztői környezethez tartozó kódelemző, ami szorosan integrálva van az Android Studio fejlesztői környezetbe. Nagyrészt Android specifikus szabályokat tartalmaz, több csoportba osztva és azon belül is prioritás szerint rendezve.

Alapértelmezetten ezeknek az ellenőrzéseknek egy része szerkesztéskor lefut az Android Studioban. A szerkesztő ki is emeli a hibákat vagy figyelmeztetéseket neked. Ez letiltható és konfigurálható, csak a jobb alsó sarokban lévő rendőr bácsi ikonra kell kattintani. Azt ajánlom, a szerkesztés közben futó ellenőrzéseket módosítsd, mert néha érezhetően belassíthatják az Android Studiot layoutok megnyitásakor.

A teljes vizsgálat az Analyze menüpont alatt található Inspect Code… opciót választva indítható el. Ez szépen rendezi neked a problémákat és egyes esetekben gyors javításokat is végre tud hajtani.

teljes lint vizsgálat eredménye

Az analízis a parancssorból is indítható a Gradle segítségével, mégpedig a lint parancs kiadásával. Ilyenkor alapértelmezetten XML és egy HTML formátumú riportot is kapsz. A HTML-t szépen lehet navigálni.

Többféleképpen ki tudod zárni az osztályokat, layoutokat a vizsgálatból:

  • @SuppressLint annotációval kódban
  • Layout fájlokban tools:ignore használatval
  • Egy lint.xml konfigurációs fájlban

Ezen kívül a build.gradle fájlban is konfigurálhatod. Itt kell ugyanis megadni a lint.xml fájl elérési útvonalát. Ebben a fájlban tudod az alkalmazott szabályok prioritását is megváltoztatni.

Findbugs

Szerk.: A post írásakor már halott volt ez a project, de még nem volt más helyette. Azóta bejelentették a Spotbugs-ot mint utódot és ki is jött 2017 októberében az első használható verzió. A bekötésére találsz példát a githubunkon. Ezt használd inkább.

Több mint 10 éves Java bájtkód elemző, ami lehetséges hibák után kutat. Nem csak saját listája van, hanem egy biztonsági és még egy nagyobb kiegészítő lista is.

Android Studioban egy IntelliJ vagy Gradle bővítmény segítségével lehet használni.
Mindkettőt testre lehet szabni, bár a Gradle plugint körülményesebb beállítani.

A szabályok különböző csoportokba (pl.: rossz gyakorlat, biztonság stb.) vannak sorolva. Ez a listán nem látszik, de egy 1–20-ig terjedő prioritásuk is van. 1 az, ami magasabb szintű hiba és a 20, ami alacsonyabb szintű. Elemzés után kapnak egy konfidencia értéket is a talált figyelmeztetések, ami 1-től 3-ig terjed. Az 1-es érték itt is a legmagasabb.

Az elemzőnél be lehet állítani az elemzés mértékét. Egy jobb elemzés több memóriát fogyaszt és lassabb, de több hibát tárhat fel, nagyobb konfidenciával. Továbbá testre szabhatod azt is, milyen prioritású hibák érdekelnek.

A hibát az IntelliJ plugin szépen grafikusan összeszedve felsorolja. A parancssor XML, HTML fájlt generál vagy egyszerűen kitol mindent a parancssori kimenetre. A HTML fájl normálisan böngészhető és a hibák magyarázatai is benne vannak. A prioritás pedig 3-féle színnel jelölve van.

PMD

Egy több nyelvhez használható forráskód elemző, ami leginkább a rossz gyakorlatok felderítésében segít. IntelliJ vagy Gradle plugin formájában lehet futtatni.

Nagyrészt Java szabályokat tartalmaz, de 3 db Android szabályt is találsz köztük. A szabályok átláthatóan csoportosítva vannak a dokumentációban és mindegyik példa kóddal van leírva.

Egy külön XML fájlban tudod konfigurálni, mely szabály csoportok fussanak és ezek közül melyik ne. A téves találatokat a kódodban tudod majd kizárni a @SuppressWarning annotációval.

Az eredmény egy XML vagy HTML formában látható vagy az IntelliJ plugin esetében grafikusan. Sajnos a HTML fájlban nincsenek benne talált hibák magyarázatai, hanem a honlapjukra dobnak. Ennek ellenére talán használhatóbb, mert itt nem hibakódok vannak a generált fájlban, hanem egy rövid mondat a hibáról.

Checkstyle

Kód stílusára vonatkozó előírások betartását segíti elő. IntelliJ és Gradle plugin is rendelkezésre áll a futtatásra.

Az ellenőrzés szabályait egy XML fájlban lehet definiálni. Parancssori futtatás után HTML, XML és parancssori kimenetet is kapsz, amiket természetesen külön-külön le is tilthatsz. A HTML kimenet osztályonként van rendezve, amiken belül fel van sorolva melyik sorral mi a probléma.

Az Android Studioban van beépített kódformázás. Persze ez nagyrészt csak a szóközök, tabulátorok és zárójelek elhelyezésében segít, de ezzel is átláthatóbb lesz a kód. Ezt testre lehet szabni a beállítások Editor menüpont Code Style opciója alatt. Ha a ctrl+alt+l (cmd+alt+l Mac alatt) parancsot használod, automatikusan formázza a kódot és XML fájlokat erre a stílusra. Verziókövető rendszerbe való feltöltéskor is tudja erre a stílusra formázni a kódot, ha bepipálod a Commit ablakban a Before Commit résznél a Reformat Code négyzetet.

SonarQube

Kicsit más eszköz mint többi, mivel ennek külön felülete van, ami egy szerveren fut. Itt lehet adminisztrálni a különböző projekteket és szabályokat. Egy elég komplex megoldás, ezért a beállítással többet kell foglalkozni, mintha egyesével raknád fel a fentieket.

Több nyelvet is tud és pluginokat is kezel, bár ezek közül vannak, amiért fizetni kell. A fenti keresők mind integrálhatóak bele. Mivel ezek mind külső függőségek és nem tudtak rajtuk könnyen változtatni, ezért megalkották a saját elemzőjüket, ami mindezeket egyesíti. Egyszerre dolgozik forrás és bájtkódon, hogy kevesebb téves találat legyen. Kb. 1600 szabály van és ehhez még hozzáveheted a Findbugs, PMD és Checkstyle és Android lint keresések eredményeit.

Magát a felületet kipróbálhatod a honlapjukon. Érdemes megnézni, mert még azt is megmutatja mennyi idő kijavítani egy-egy hibát.

Beállítás

Legjobb ha a Gradle pluginokat használod, így verziókezelőből letöltve bárhol használhatod. Ráadásul, ha csapatban dolgozol ők is tudják használni a kódelemzőket, nem kell mindenkinek telepítenie valamit.

Nézd meg az android-quality-starter GitHub repót. Benne van minden. Arról van szó, hogy a projekteden belül létrehozol egy külön quality mappát a beállításoknak.
Ezen belül egy quality.gradle fájlt a Gradle beállításoknak. Ez fogja tartalmazni a Gradle plugin beállításokat.
Ezt becsatolod a build.gradle fájlba:


apply from: '../quality/quality.gradle'

A keresők konfigurációs fájljai a quality mappán belül almappákban vannak. Javaslom egyenként próbáld ki és állítsd be őket. Az annotációs processzort vagy reflectiont használó könyvtárak szinte mind téves figyelmeztetéseket okoznak, ezért ezeket ki kell majd zárni valamilyen módon.

Érdemes fokozatosan bevezetni azokat a szabályokat, amik a kód stílusára vonatkoznak. Így alkalmazkodni lehet hozzájuk és nem lesz túl sok teher a változás. Ennek ellenére a szabályok segíthetnek más megvilágításba helyezni a problémákat. Ne add fel vagy kapcsolj ki egy szabályt, ha első látásra nem tudod megoldani.

Az összes vizsgálatot a check Gradle paranccsal lehet futtatni. Mivel külön mappában van minden, könnyen behúzhatod más projektekhez.

Eredmény

Ha be lett állítva minden és megvannak a találatok, akkor neki lehet esni a javításnak. Persze itt adódnak gondok. Ugyanis nem fogja senki sem futtatni ezeket a teszteket, mert sokáig tart, körülményes, az eredmény nem könnyen átlátható stb.
Itt jön be a képbe a CI azaz Continous Integration. Egy központi szerver, ami lefordítja a kódot és szól, ha baki történt. De ez egy másik alkalomra szóló mese.

Vaszil Ádám

Már sok-sok éve szeretne programozó lenni, de mivel ennyi nyelvet nehéz megtanulni, ezért inkább csak a Javara koncentrál.

Vaszil Ádám

Hozzászólások