Ezarri analisi estatikoa prozesuan, akatsak aurkitzeko erabili beharrean

Artikulu hau idaztera bultzatu ninduen gero eta arreta gehiago ematen ari zaizkidan analisi estatikoei buruzko material kopuru handiak. Lehenik eta behin, hau PVS-studio bloga, HabrΓ©-n aktiboki sustatzen duena bere tresnak kode irekiko proiektuetan aurkitutako akatsen berrikuspenen laguntzaz. Duela gutxi PVS-studioa ezarri da Java euskarria, eta, jakina, IntelliJ IDEA-ren garatzaileek, zeinaren barne-analisia ziurrenik gaur egungo Javarako aurreratuena dena, ezin izan urrun egon.

Horrelako iritziak irakurtzean, elixir magiko bati buruz ari garela sentitzen duzu: sakatu botoia, eta hemen dago - akatsen zerrenda zure begien aurrean. Badirudi analizatzaileak hobetu ahala, automatikoki gero eta akats gehiago topatuko direla, eta robot horiek eskaneatutako produktuak gero eta hobeak izango direla, gure aldetik inolako ahaleginik egin gabe.

Baina ez dago elixir magikorik. "Hona hemen gure robotak aurki ditzakeen gauzak" bezalako mezuetan normalean hitz egiten ez denari buruz hitz egin nahiko nuke: zer egin ezin duten analizatzaileek, zein den bere benetako rola eta lekua softwarea entregatzeko prozesuan, eta nola inplementatu behar bezala. .

Ezarri analisi estatikoa prozesuan, akatsak aurkitzeko erabili beharrean
Trinketa (iturria: wikipedia).

Analizatzaile estatikoek inoiz egin dezaketena

Zer da iturburu-kodearen azterketa, ikuspuntu praktikotik? Iturburu-kode batzuk ematen ditugu sarrera gisa, eta irteera gisa, denbora gutxian (probak exekutatzen baino askoz laburragoa) gure sistemari buruzko informazio batzuk lortzen ditugu. Oinarrizko eta matematikoki gaindiezina den muga da informazio-klase estu samarra soilik lor dezakegula horrela.

Analisi estatikoa erabiliz konpondu ezin den arazo baten adibiderik ezagunena da ixteko arazoa: Programa baten iturburu-kodetik denbora finitu batean begizta edo amaituko den zehaztu dezakeen algoritmo orokor bat garatzea ezinezkoa dela frogatzen duen teorema da. Teorema honen luzapena da Riceren teorema, funtzio konputagarrien edozein propietate ez hutsaletarako, programa arbitrario batek propietate hori duen funtzio bat ebaluatzen duen ala ez zehaztea algoritmoki konpongaitza den problema bat da. Esaterako, ezinezkoa da edozein iturburu-kodetik zehaztu dezakeen analizatzaile bat idaztea aztertzen ari den programa zenbaki oso baten karratua kalkulatzen duen algoritmo baten inplementazioa den ala ez.

Beraz, analizatzaile estatikoen funtzionaltasunak muga gaindiezinak ditu. Analizatzaile estatiko batek ezingo du inoiz detektatu kasu guztietan, adibidez, "null erakuslearen salbuespena" agertzea nullaren balioa onartzen duten hizkuntzetan, edo kasu guztietan "" baten agerraldia zehazteko. atributua ez da aurkitu" dinamikoki idatzitako hizkuntzetan. Analizatzaile estatiko aurreratuenak egin dezakeen guztia kasu bereziak nabarmentzea da, zeinen kopurua, zure iturburu-kodearekin izan daitezkeen arazo guztien artean, gehiegikeriarik gabe, ontziaren tanta bat da.

Analisi estatikoa ez da akatsak aurkitzea

Aurrekotik ondorioztatzen da: analisi estatikoa ez da programa bateko akatsen kopurua murrizteko bitartekoa. Ausartuko nintzateke esatera: zure proiektuan lehen aldiz aplikatzen denean, toki "interesgarriak" aurkituko ditu kodean, baina, ziurrenik, ez du zure programaren kalitatean eragiten duen akatsik aurkituko.

Analizatzaileek automatikoki aurkitutako akatsen adibideak ikusgarriak dira, baina ez dugu ahaztu behar adibide hauek kode-oinarri handien multzo handi bat eskaneatu zirela aurkitu zirela. Printzipio beraren arabera, pasahitz soil batzuk hainbat kontutan probatzeko aukera duten hackerrek azkenean pasahitz sinplea duten kontuak aurkitzen dituzte.

Horrek esan nahi du ez dela analisi estatikoa erabili behar? Noski ezetz! Eta arrazoi beragatik merezi du pasahitz berri bakoitza egiaztatzea pasahitz "soilen" zerrendan sartuta dagoela ziurtatzeko.

Analisi estatikoa akatsak aurkitzea baino gehiago da

Izan ere, azterketaren bidez ia ebazten diren arazoak askoz zabalagoak dira. Azken finean, oro har, analisi estatikoa abian jarri aurretik egindako iturburu-kodeen egiaztapena da. Hona hemen egin ditzakezun gauza batzuk:

  • Kodetze estiloa egiaztatzea hitzaren zentzurik zabalenean. Honek formatua egiaztatzea, parentesi hutsak/gehienak erabiltzea, neurrien atalaseak ezartzea bezalako lerro kopurua/metodo baten konplexutasun ziklomatikoa, etab. - kodearen irakurgarritasuna eta mantentzea oztopatzen duen guztia. Javan, horrelako tresna bat Checkstyle da, Python-en - flake8. Klase honetako programei "linters" deitu ohi zaie.
  • Kode exekutagarria ez ezik, aztertu daiteke. JSON, YAML, XML, .properties bezalako baliabide-fitxategiak automatikoki egiaztatu daitezke (eta beharko lirateke!) baliozkotasuna duten. Azken finean, hobe da jakitea JSON egitura hautsita dagoela parekatu gabeko komatxo batzuen ondorioz Pull Request egiaztapen automatikoaren hasierako fasean probaren exekuzioan edo exekuzio-denboran baino? Tresna egokiak eskuragarri daude: adibidez. YAMLint, JSONLint.
  • Konpilazioa (edo programazio-lengoaia dinamikoetarako analizatzea) analisi estatiko mota bat ere bada. Oro har, konpilatzaileak gai dira iturburu-kodearen kalitatearekin arazoak adierazten dituzten abisuak sortzeko eta ez dira alde batera utzi behar.
  • Batzuetan, konpilazioa kode exekutagarria konpilatzea baino gehiago da. Adibidez, formatuan dokumentazioa baduzu AsciiDoctor, orduan HTML/PDF bihurtzeko unean AsciiDoctor kudeatzailea (Maven plugina) abisuak eman ditzake, adibidez, hautsitako barne estekei buruz. Eta hori arrazoi ona da dokumentazio aldaketekin Pull Request ez onartzeko.
  • Zuzenketa ortografikoa ere analisi estatiko mota bat da. Erabilgarritasuna aspell Gai da ortografia egiaztatzeko dokumentazioan ez ezik, programen iturburu-kodeetan ere (iruzkinak eta literalak) hainbat programazio-lengoaiatan, C/C++, Java eta Python barne. Erabiltzailearen interfazean edo dokumentazioan akats ortografikoak ere akats bat da!
  • Konfigurazio probak (zer diren buruz - ikus. hau ΠΈ hau txostenak), pytest bezalako proba unitateko exekuzio-denboran exekutatu arren, analisi estatiko mota bat ere bada, ez baitute iturburu-koderik exekutatzen exekutatzen diren bitartean.

Ikusten duzunez, zerrenda honetan akatsak bilatzea du garrantzi gutxieneko papera, eta gainerako guztia eskuragarri dago kode irekiko doako tresnak erabiliz.

Analisi estatiko hauetatik zein erabili beharko zenuke zure proiektuan? Noski, zenbat eta gehiago hobe! Gauza nagusia behar bezala ezartzea da, gehiago eztabaidatuko dena.

Bidalketa kanalizazioa etapa anitzeko iragazki gisa eta analisi estatikoa lehen fase gisa

Etengabeko integrazioaren metafora klasikoa aldaketak jariotzen dituen kanalizazio bat da, iturburu-kodeen aldaketetatik hasi eta ekoizpenera arte. Hodi honetako etapen sekuentzia estandarrak honelakoa da:

  1. analisi estatikoa
  2. bilketa
  3. unitate-probak
  4. integrazio probak
  5. UI probak
  6. eskuzko egiaztapena

Hodiaren N. fasean baztertutako aldaketak ez dira N+1 fasera pasatzen.

Zergatik zehazki horrela eta ez bestela? Hodiaren probaren zatian, probalariek probaren piramide ezaguna ezagutuko dute.

Ezarri analisi estatikoa prozesuan, akatsak aurkitzeko erabili beharrean
Test piramidea. Iturria: artikuluan Martin Fowler.

Piramide honen behealdean idazteko errazagoak diren, exekutatzeko azkarragoak eta huts egiteko joerarik ez duten probak daude. Hori dela eta, gehiago izan beharko lukete, kode gehiago estali beharko lukete eta lehenik exekutatu beharko lirateke. Piramidearen goialdean, alderantziz gertatzen da, beraz, integrazio eta UI proba kopurua behar den minimora murriztu behar da. Kate honetako pertsona baliabiderik garestiena, motelena eta fidagarriena da, beraz, amaieran dago eta aurreko etapetan akatsik aurkitu ezean bakarrik egiten du lana. Hala ere, printzipio berberak erabiltzen dira probarekin zuzenean lotuta ez dauden zatietan kanalizazioa eraikitzeko!

Analogia bat eskaini nahiko nuke etapa anitzeko ura iragazteko sistema baten moduan. Ur zikina (akatsekin aldatzen da) sarrerara hornitzen da; irteeran ur garbia jaso behar dugu, eta bertan nahi ez diren kutsatzaile guztiak ezabatu dira.

Ezarri analisi estatikoa prozesuan, akatsak aurkitzeko erabili beharrean
Etapa anitzeko iragazkia. Iturria: Wikimedia Commons

Dakizuenez, garbiketa-iragazkiak ondorengo kaskada bakoitzak kutsatzaileen zati gero eta finagoa iragazi ahal izateko diseinatuta daude. Aldi berean, arazketa larrien kaskadek errendimendu handiagoa eta kostu txikiagoa dute. Gure analogian, horrek esan nahi du sarrera-kalitateko ateak azkarragoak direla, abiarazteko esfortzu gutxiago behar dutela eta funtzionamenduan itxuragabeagoak direla - eta hau da eraikitzen diren sekuentzia. Analisi estatikoaren eginkizuna, orain ulertzen dugun bezala, akatsik gordinenak bakarrik kentzeko gai dena, "lokatza" sarearen papera da iragazkien kaskadaren hasieran.

Analisi estatikoak berez ez du azken produktuaren kalitatea hobetzen, β€œlokatz-iragazkiak” ura edagarri bihurtzen ez duen bezala. Hala ere, hodiaren beste elementu batzuekin batera, bere garrantzia nabaria da. Etapa anitzeko iragazki batean irteerako etapak sarrerako etapak egiten duten guztia harrapatzeko gai badira ere, argi dago zer ondorio ekarriko dituen garbiketa-etapa finekin bakarrik, sarrera-etaparik gabe, konpontzen saiakerak.

"Lokatz-tranpa"ren helburua ondorengo kaskadak akats oso larriak harrapatzea da. Adibidez, gutxienez, kodearen berrikuspena egiten duen pertsona ez da gaizki formateatutako kodea eta ezarritako kodeketa estandarrak urratzeagatik (adibidez, parentesi gehigarriak edo adar sakonegiak habiaratuta). NPEak bezalako akatsak unitateko probek harrapatu beharko lituzkete, baina proba baino lehen ere analizatzaileak akatsen bat gertatuko dela adierazten badigu, horrek nabarmen azkartuko du konponketa.

Uste dut orain argi dagoela zergatik analisi estatikoak ez duen produktuaren kalitatea hobetzen noizean behin erabiltzen bada, eta etengabe erabili behar da akats larrien aldaketak iragazteko. Analizatzaile estatiko bat erabiltzeak zure produktuaren kalitatea hobetuko duen ala ez galdetzea, gutxi gorabehera: "Urmael zikin batetik hartutako ura hobetuko al da edateko kalitatea kolador batetik igarotzen bada?"

Oinarrizko proiektu batean ezartzea

Galdera praktiko garrantzitsu bat: nola ezarri analisi estatikoa etengabeko integrazio-prozesuan "kalitatearen ate" gisa? Proba automatikoen kasuan, dena begi-bistakoa da: proba multzo bat dago, horietako edozeinen hutsegite nahikoa arrazoi da muntaiak kalitate-atea gainditu ez duela uste izateko. Analisi estatiko baten emaitzetan oinarritutako ate bat modu berean instalatzeko saiakerak huts egiten du: analisi-abisu gehiegi daude ondarearen kodean, ez dituzu guztiz alde batera utzi nahi, baina ezinezkoa da produktu bat bidaltzeari uztea. analizatzaileen abisuak dituelako bakarrik.

Lehen aldiz erabiltzen denean, analizatzaileak abisu ugari sortzen ditu edozein proiektutan, eta horietako gehienak ez daude produktuaren funtzionamendu egokiarekin erlazionatuta. Ezinezkoa da iruzkin horiek guztiak batera zuzentzea, eta asko ez dira beharrezkoak. Azken finean, badakigu gure produktuak bere osotasunean funtzionatzen duela, analisi estatikoa sartu aurretik ere!

Ondorioz, asko analisi estatikoa noizean behin erabiltzera mugatzen dira, edo informazio moduan soilik erabiltzen dute, muntaian zehar analizatzaileen txostena besterik gabe igortzen denean. Inongo analisirik ezaren baliokidea da, izan ere, dagoeneko abisu asko baditugu, kodea aldatzean besteren bat agertzea (larria bada ere) oharkabean pasatzen da.

Kalitatezko ateak sartzeko metodo hauek ezagutzen dira:

  • Abisu-kopuru osoaren edo kode-lerroen artean zatitutako abisu-kopuruaren muga ezartzea. Horrek gaizki funtzionatzen du, halako ate batek libreki uzten baitu akats berriak dituzten aldaketak igarotzen, betiere haien muga gainditzen ez den bitartean.
  • Une jakin batean, kodean dauden abisu zahar guztiak ez ikusi bezala konpontzea eta abisu berriak gertatzen direnean eraikitzeari uko egitea. Funtzionalitate hau PVS-studio-k eta lineako baliabide batzuek eskaintzen dute, adibidez, Codacy-k. Ez nuen PVS-studioan lan egiteko aukerarik izan, Codacy-rekin dudan esperientziagatik, haien arazo nagusia zer den errore "zahar" eta zer den "berri" zehaztea algoritmo konplexu samarra da, beti funtzionatzen ez duena. behar bezala, batez ere fitxategiak asko aldatzen badira edo izena aldatzen badute. Nire esperientziaren arabera, Codacy-k abisu berriak baztertu ditzake tira-eskaera batean, eta, aldi berean, tira-eskaerarik ez du pasatzen PR jakin baten kodearen aldaketekin erlazionatuta ez dauden abisuengatik.
  • Nire ustez, irtenbiderik eraginkorrena liburuan azaltzen dena da Etengabeko erak β€œTrinketa metodoa”. Oinarrizko ideia da analisi estatikoko abisu kopurua bertsio bakoitzaren propietatea dela, eta abisu kopurua handitzen ez duten aldaketak soilik onartzen direla.

Trinketa

Honela funtzionatzen du:

  1. Hasierako fasean, aztertzaileek aurkitutako kodean abisu-kopurua askatzeari buruzko metadatuetan erregistro bat egiten da. Beraz, upstream eraikitzen duzunean, zure biltegi-kudeatzaileak "7.0.2 bertsioa" ez ezik "7.0.2 bertsioa 100500 kontrol-estilo abisu dituena" idazten du. Biltegi-kudeatzaile aurreratu bat erabiltzen baduzu (adibidez, Artifactory), zure bertsioari buruzko metadatuak gordetzea erraza da.
  2. Orain tira-eskaera bakoitzak, eraikitakoan, sortzen diren abisu kopurua uneko bertsioan eskuragarri dauden abisu kopuruarekin alderatzen du. PR-k kopuru hori handitzen badu, orduan kodeak ez du analisi estatikorako kalitate-atea gainditzen. Abisu kopurua murrizten bada edo aldatzen ez bada, igarotzen da.
  3. Hurrengo bertsioan, berriro kalkulatutako abisu-kopurua berriro grabatuko da bertsioaren metadatuetan.

Beraz, apurka-apurka baina etengabe (trinketa batek funtzionatzen duenean bezala), abisu kopurua zerora joango da. Jakina, sistema engainatu daiteke abisu berri bat sartuz, baina beste norbaitena zuzenduz. Hau normala da, distantzia luzean emaitzak ematen dituelako: abisuak zuzentzen dira, oro har, ez banan-banan, baina aldi berean mota jakin bateko talde batean, eta erraz ken daitezkeen abisu guztiak nahiko azkar ezabatzen dira.

Grafiko honek Checkstyle-ko abisu-kopurua erakusten du "trinketa" bat martxan dagoen sei hilabeteetan gure OpenSource proiektuetako bat. Abisu-kopurua neurri handi batean gutxitu da, eta hori modu naturalean gertatu da, produktuaren garapenarekin batera!

Ezarri analisi estatikoa prozesuan, akatsak aurkitzeko erabili beharrean

Metodo honen bertsio aldatua erabiltzen dut, proiektuaren moduluaren eta analisi-tresnaren araberako abisuak bereizita zenbatuz, eta YAML fitxategi bat sortzen da, honelako itxura duen eraikitze metadatuak dituena:

celesta-sql:
  checkstyle: 434
  spotbugs: 45
celesta-core:
  checkstyle: 206
  spotbugs: 13
celesta-maven-plugin:
  checkstyle: 19
  spotbugs: 0
celesta-unit:
  checkstyle: 0
  spotbugs: 0

Edozein CI sistema aurreratuetan, ratchet edozein analisi estatikoko tresnatarako inplementa daiteke pluginetan eta hirugarrenen tresnetan fidatu gabe. Analizatzaile bakoitzak bere txostena sortzen du testu sinplean edo XML formatuan, aztertzeko erraza dena. CI gidoian beharrezko logika idaztea besterik ez da geratzen. Jenkins eta Artifactory-n oinarritutako gure kode irekiko proiektuetan nola inplementatzen den ikus dezakezu Hemen edo Hemen. Bi adibideak liburutegiaren araberakoak dira ratchetlib: metodoa countWarnings() Checkstyle eta Spotbugs-ek ohiko moduan sortutako fitxategietan xml etiketak zenbatzen ditu, eta compareWarningMaps() trinketa bera ezartzen du, kategorietako edozein abisu kopurua handitzen denean errore bat botatzen du.

"Ratchet"-aren ezarpen interesgarri bat posible da iruzkinen, testu literalen eta dokumentazioaren ortografia aspell erabiliz aztertzeko. Dakizuenez, ortografia egiaztatzean, hiztegi estandarrean ezezagunak diren hitz guztiak ez dira okerrak; erabiltzailearen hiztegian gehi daitezke. Hiztegi pertsonalizatu bat proiektuaren iturburu-kodearen zati egiten baduzu, ortografia-kalitatearen atea honela formulatu daiteke: aspell exekutatu hiztegi estandar eta pertsonalizatu batekin. ez luke behar ez aurkitu akats ortografikoak.

Analizatzailearen bertsioa konpontzearen garrantziari buruz

Amaitzeko, kontuan hartu beharreko puntua da analisia zure entrega-bidean nola ezartzen duzun, analizatzailearen bertsioa konpondu behar dela. Analizatzailea berez eguneratzen uzten baduzu, hurrengo tira-eskaera muntatzean, akats berriak "ager" daitezke, kode-aldaketekin erlazionatuta ez daudenak, baina analizatzaile berriak akats gehiago aurkitzeko gai izatearekin zerikusia dutenak - eta honek tira eskaerak onartzeko prozesua hautsi egingo du. Analizatzaile bat eguneratzeak ekintza kontziente bat izan behar du. Hala ere, muntaia-osagai bakoitzaren bertsioaren finkapen zurruna behar-beharrezko baldintza eta eztabaidarako gaia da, oro har.

Findings

  • Analisi estatikoak ez dizu akatsik aurkituko eta ez du zure produktuaren kalitatea hobetuko aplikazio bakar baten ondorioz. Kalitatearen eragin positiboa entrega-prozesuan etengabe erabiltzearen bidez soilik lor daiteke.
  • Akatsak aurkitzea ez da analisiaren zeregin nagusia; funtzio erabilgarri gehienak kode irekiko tresnetan daude eskuragarri.
  • Ezarri kalitate-ateak analisi estatikoen emaitzetan oinarrituta entrega-bidearen lehen fasean, "trinketa" bat erabiliz, ondare-koderako.

Erreferentziak

  1. Etengabeko erak
  2. A. Kudryavtsev: Programaren azterketa: nola ulertu programatzaile ona zarela Kode-analisi metodo ezberdinen berri eman (estatikoa ez ezik!)

Iturria: www.habr.com

Gehitu iruzkin berria