Innleiða truflanir greiningu í ferlið, frekar en að leita að villum með því

Ég var innblásin til að skrifa þessa grein af miklum fjölda efna um kyrrstöðugreiningar sem eru sífellt að rekast á. Í fyrsta lagi þetta PVS-stúdíó blogg, sem kynnir sig virkan á Habré með umsögnum um villur sem tól þeirra fundu í opnum hugbúnaði. PVS-stúdíó nýlega innleitt Java stuðningur, og auðvitað þróunaraðilar IntelliJ IDEA, þar sem innbyggður greiningartæki er líklega sá fullkomnasta fyrir Java í dag, gat ekki verið í burtu.

Þegar þú lest slíkar umsagnir fær maður á tilfinninguna að við séum að tala um töfraelixír: ýttu á hnappinn og hér er hann - listi yfir galla fyrir framan augun. Svo virðist sem eftir því sem greiningartækin batna verði sjálfkrafa fleiri og fleiri villur og vörurnar sem skannaðar eru af þessum vélmennum verða betri og betri, án nokkurrar fyrirhafnar af okkar hálfu.

En það eru engir töfraelixírar. Mig langar að tala um það sem venjulega er ekki rætt í færslum eins og „hér eru hlutir sem vélmenni okkar getur fundið“: hvað greiningartæki geta ekki gert, hvert er raunverulegt hlutverk þeirra og staður í afhendingarferli hugbúnaðarins og hvernig á að útfæra þá á réttan hátt.

Innleiða truflanir greiningu í ferlið, frekar en að leita að villum með því
Ratchet (heimild: Wikipedia).

Hvað Static Analyzers geta aldrei gert

Hvað er, frá hagnýtu sjónarhorni, frumkóðagreining? Við matum inn sumar heimildir og á stuttum tíma (mun styttri en keyrslupróf) fáum við einhverjar upplýsingar um kerfið okkar. Grundvallar- og stærðfræðilega óyfirstíganleg takmörkun er sú að við getum þannig fengið aðeins frekar þröngan flokk upplýsinga.

Frægasta dæmið um vandamál sem ekki er hægt að leysa með kyrrstöðugreiningu er stöðva vandamál: þetta er setning sem sannar að það er ómögulegt að þróa almennt reiknirit sem myndi ákvarða út frá frumkóða forritsins hvort það mun lykkja eða enda á endanlegum tíma. Framlenging á þessari setningu er Setning Riceþar sem fram kemur að fyrir hvers kyns óléttvægan eiginleika reiknanlegra falla, að ákvarða hvort handahófskennt forrit meti fall með slíkum eiginleikum er algrím óleysanlegt vandamál. Til dæmis er ómögulegt að skrifa greiningartæki sem getur ákvarðað út frá hvaða frumkóða sem er hvort greinda forritið sé útfærsla á reiknirit sem reiknar til dæmis út heiltölu í veldi.

Þannig hefur virkni statískra greiningartækja óyfirstíganlegar takmarkanir. Stöðugur greiningartæki mun aldrei geta ákvarðað í öllum tilfellum eins og til dæmis tilvik "núllbendisundtekningar" á núlltækum tungumálum, eða í öllum tilfellum til að ákvarða tilvik "eiginleika finnst ekki" í tungumálum með kraftmikla vélritun. Allt sem fullkomnasta stöðugreiningartækið getur gert er að varpa ljósi á sérstök tilvik þar sem fjöldi þeirra, meðal allra hugsanlegra vandamála með frumkóðann þinn, er, án ýkju, dropi í hafið.

Stöðug greining er ekki leit að villum

Niðurstaðan leiðir af ofangreindu: kyrrstöðugreining er ekki leið til að fækka galla í forriti. Ég leyfi mér að fullyrða að þegar það er fyrst notað á verkefnið þitt mun það finna "skemmtilega" staði í kóðanum, en líklegast mun það ekki finna neina galla sem hafa áhrif á gæði forritsins þíns.

Dæmin um galla sem greiningartækin finna sjálfkrafa eru áhrifamikil, en við ættum ekki að gleyma því að þessi dæmi fundust með því að skanna stórt sett af stórum kóðabasa. Samkvæmt sömu reglu, finna kex sem geta prófað nokkur einföld lykilorð á fjölda reikninga að lokum þá reikninga sem hafa einfalt lykilorð.

Þýðir þetta að ekki ætti að nota truflanir? Auðvitað ekki! Og nákvæmlega af sömu ástæðu hvers vegna það er þess virði að athuga hvert nýtt lykilorð til að komast inn á stöðvunarlistann yfir „einföld“ lykilorð.

Statísk greining er meira en að finna villur

Reyndar eru vandamálin sem eru nánast leyst með greiningu miklu víðtækari. Þegar öllu er á botninn hvolft, almennt, er kyrrstöðugreining öll athugun á frumkóðum sem er framkvæmd áður en þeir eru settir af stað. Hér eru nokkur atriði sem þú getur gert:

  • Athugaðu kóðunarstíl í víðasta skilningi þess orðs. Þetta felur í sér bæði að athuga snið og leita að notkun tómra/auka sviga, setja þröskulda á mælikvarða eins og fjölda lína / flókið hringlaga aðferð o.s.frv. - allt sem mögulega gerir kóða læsilegri og viðhaldshæfari. Í Java er þetta tól Checkstyle, í Python er það flake8. Forrit í þessum flokki eru venjulega kölluð "linters".
  • Ekki aðeins er hægt að greina keyranlegan kóða. Auðlindaskrár eins og JSON, YAML, XML, .properties geta (og ætti!) verið sjálfkrafa athugað með tilliti til gildis. Er ekki betra að komast að því að vegna sumra ópörðra tilvitnana er JSON uppbyggingin rofin á frumstigi sjálfvirkrar Pull Request löggildingar en þegar prófanir eru framkvæmdar eða á keyrslutíma? Viðeigandi verkfæri eru í boði: td. YAMLlint, JSONLint.
  • Samantekt (eða þáttun fyrir kvik forritunarmál) er líka eins konar kyrrstöðugreining. Að jafnaði eru þýðendur færir um að gefa út viðvaranir sem benda til vandamála með gæði frumkóðans og ætti ekki að hunsa þær.
  • Stundum snýst samantekt ekki bara um að setja saman keyranlegan kóða. Til dæmis, ef þú ert með skjöl á formi AsciiDoctor, þá á því augnabliki sem það umbreytist í HTML/PDF meðhöndlun AsciiDoctor (Maven viðbót) getur gefið út viðvaranir, til dæmis um bilaða innri hlekki. Og þetta er góð ástæða til að samþykkja ekki Pull beiðnina með breytingum á skjölum.
  • Villuleit er líka tegund kyrrstöðugreiningar. Gagnsemi aspell er fær um að athuga stafsetningu ekki aðeins í skjölum, heldur einnig í frumkóðum forrita (athugasemdir og bókstafir) á mismunandi forritunarmálum, þar á meðal C/C++, Java og Python. Stafsetningarvilla í notendaviðmóti eða skjölum er líka galli!
  • Stillingarpróf (sjá hvað það er þetta и þetta skýrslur), þó að þær séu keyrðar í einingaprófunartíma eins og pytest, eru þær í raun líka eins konar kyrrstöðugreiningar, þar sem þær keyra ekki frumkóða meðan þær eru keyrðar.

Eins og þú sérð tekur það minnsta hlutverk að finna villur á þessum lista og allt annað er fáanlegt með því að nota ókeypis opinn hugbúnað.

Hvaða af þessum tegundum kyrrstöðugreiningar ætti að nota í verkefninu þínu? Auðvitað, því meira, því betra! Aðalatriðið er að útfæra það rétt, sem verður rætt frekar.

Afhendingarleiðslu sem fjölþrepa sía og kyrrstöðugreining sem fyrsta hlaup hennar

Klassíska myndlíkingin fyrir samfellda samþættingu er leiðslan (pípalínan) sem breytir flæði í gegnum - frá því að breyta frumkóða til afhendingar til framleiðslu. Stöðluð röð þrepa þessarar leiðslu lítur svona út:

  1. kyrrstöðugreining
  2. samantekt
  3. einingapróf
  4. samþættingarpróf
  5. HÍ próf
  6. handvirkt athugun

Breytingar sem hafnað var á N. stigi leiðslunnar eru ekki fluttar til stigi N+1.

Af hverju nákvæmlega svona og ekki öðruvísi? Í prófunarhluta leiðslunnar munu prófunaraðilar þekkja hinn vel þekkta prófunarpýramída.

Innleiða truflanir greiningu í ferlið, frekar en að leita að villum með því
próf pýramída. Heimild: grein Martin Fowler.

Neðst í þessum pýramída eru próf sem er auðveldara að skrifa, hlaupa hraðar og hafa ekki tilhneigingu til að vera falskur jákvæður. Þess vegna ættu þeir að vera fleiri, þeir ættu að ná yfir meiri kóða og vera keyrðir fyrst. Efst í pýramídanum er þessu öfugt farið og því ætti að fækka samþættingar- og notendaprófum niður í nauðsynlegt lágmark. Maðurinn í þessari keðju er dýrasta, hægasta og óáreiðanlegasta auðlindin, þannig að hann er á endanum og vinnur aðeins ef fyrri stig fundu enga galla. Hins vegar, samkvæmt sömu lögmálum, er leiðslan byggð í hlutum sem tengjast ekki prófunum beint!

Mig langar að bjóða upp á hliðstæðu í formi fjölþrepa vatnssíunarkerfis. Óhreint vatn er veitt til inntaksins (breytist með göllum), við úttakið verðum við að fá hreint vatn, þar sem öllum óæskilegum aðskotaefnum er útrýmt.

Innleiða truflanir greiningu í ferlið, frekar en að leita að villum með því
Fjölþrepa sía. Heimild: Wikimedia Commons

Eins og þú veist eru hreinsunarsíur hannaðar á þann hátt að hvert næsta foss getur síað út sífellt minna brot af mengunarefnum. Á sama tíma hafa grófari hreinsunarfall meiri afköst og lægri kostnað. Í samlíkingu okkar þýðir þetta að inntaksgæðahliðin eru hraðari, þurfa minni fyrirhöfn til að byrja og eru sjálf tilgerðarlausari í rekstri - og þetta er nákvæmlega röðin sem þau eru byggð í. Hlutverk kyrrstöðugreiningar, sem, eins og við skiljum núna, er fær um að eyða aðeins grófustu göllunum, er hlutverk „leðju“ í byrjun síufallsins.

Stöðug greining í sjálfu sér bætir ekki gæði lokaafurðarinnar, rétt eins og „leðjugildra“ gerir vatn ekki drykkjarhæft. Og samt, eins og aðrir þættir færibandsins, er mikilvægi þess augljóst. Þrátt fyrir að í fjölþrepa síu séu úttaksþrepin hugsanlega fær um að fanga allt eins og inntaksþrepin, þá er ljóst hvaða afleiðingar tilraun til að komast af með aðeins fínhreinsunarþrep, án inntaksþrepa, mun leiða til.

Tilgangur "leðjusafnarans" er að afferma síðari fossa frá því að fanga mjög grófa galla. Til dæmis, að minnsta kosti, ætti kóðagagnrýnandi ekki að láta trufla sig af rangt sniðnum kóða og broti á viðurkenndum kóðunarviðmiðum (eins og auka sviga eða of djúpt hreiður greinar). Villur eins og NPE ættu að vera gripnar með einingaprófum, en ef greiningartækið gefur okkur jafnvel fyrir prófunina til kynna að villan verði óumflýjanlega að gerast, mun þetta verulega flýta fyrir lagfæringu hennar.

Ég held að það sé nú ljóst hvers vegna kyrrstöðugreining bætir ekki gæði vöru ef hún er notuð einstaka sinnum, og ætti að nota hana stöðugt til að sía út breytingar með stórum göllum. Að spyrja hvort notkun kyrrstöðugreiningartækis muni bæta gæði vörunnar jafngildir nokkurn veginn því að spyrja „Munu drykkjargæði vatns sem tekið er úr óhreinri tjörn batna ef það fer í gegnum sigti?

Innleiðing í arfleifð verkefni

Mikilvæg hagnýt spurning: hvernig á að innleiða kyrrstöðugreiningu í ferli stöðugrar samþættingar sem "gæðahlið"? Þegar um sjálfvirkar prófanir er að ræða er allt augljóst: það er sett af prófum, bilun á einhverju þeirra er næg ástæða til að ætla að samsetningin hafi ekki staðist gæðahliðið. Tilraun til að setja upp hlið á sama hátt byggt á niðurstöðum kyrrstöðugreiningar mistekst: það eru of margar greiningarviðvaranir í eldri kóðanum, þú vilt ekki hunsa þær algjörlega, en það er líka ómögulegt að stöðva afhendingu vöru bara vegna þess að hún inniheldur greiningarviðvaranir.

Þegar greiningartækið er notað í fyrsta skipti gefur hann frá sér gríðarlegan fjölda viðvarana við hvaða verkefni sem er, langflestar þeirra tengjast ekki réttri virkni vörunnar. Það er ómögulegt að leiðrétta allar þessar athugasemdir í einu og margar þeirra eru ekki nauðsynlegar. Þegar öllu er á botninn hvolft vitum við að varan okkar í heild virkar, jafnvel fyrir kynningu á kyrrstöðugreiningu!

Fyrir vikið takmarka margir sig við tímabundna notkun á kyrrstöðugreiningu, eða nota hana aðeins í upplýsingaham, þegar greiningarskýrslan er einfaldlega gefin út við samsetningu. Þetta jafngildir því að engin greiningar séu fyrir hendi, því ef við höfum nú þegar fullt af viðvörunum, þá fer óséður um að önnur (sama hversu alvarlega sem er) þegar kóðinn breytist óséður.

Eftirfarandi leiðir til að kynna gæðahlið eru þekktar:

  • Setur takmörk á heildarfjölda viðvarana, eða fjölda viðvarana deilt með fjölda kóðalína. Þetta virkar ekki vel, því slíkt hlið sleppir frjálslega breytingum með nýjum göllum þar til farið er yfir mörk þeirra.
  • Að lagfæra, á einhverjum tímapunkti, allar gamlar viðvaranir í kóðanum sem hunsaðar og mistakast við smíðina þegar nýjar viðvaranir koma fram. Þessi virkni er veitt af PVS-stúdíóinu og sumum auðlindum á netinu, svo sem Codacy. Ég hafði ekki tækifæri til að vinna í PVS-stúdíó, eins og fyrir mína reynslu af Codacy, þá er aðalvandamálið þeirra að skilgreiningin á því hvað er "gamalt" og hvað er "nýtt" villa er frekar flókið reiknirit sem gerir það ekki virka alltaf rétt, sérstaklega ef skrár eru mikið breyttar eða endurnefna. Í minningunni gat Codacy sleppt nýjum viðvörunum í pull request og á sama tíma ekki sleppt pull request vegna viðvarana sem tengdust ekki breytingum á kóða þessa PR.
  • Að mínu mati er skilvirkasta lausnin lýst í bókinni Stöðug Afhending "ratcheting" aðferð. Meginhugmyndin er sú að eiginleiki hverrar útgáfu er fjöldi viðvarana um stöðugreiningu og aðeins breytingar sem ekki auka heildarfjölda viðvarana eru leyfðar.

Ratchet

Það virkar svona:

  1. Á upphafsstigi er skráning í útgáfu lýsigögnum um fjölda viðvarana í kóðanum sem greiningartækin fundu útfærð. Svona, þegar þú byggir andstreymis, er geymslustjórinn þinn skrifaður ekki bara "útgáfa 7.0.2", heldur "útgáfa 7.0.2 sem inniheldur 100500 viðvaranir á eftirlitsstíl". Ef þú ert að nota háþróaðan geymslustjóra (eins og Artifactory) er auðvelt að geyma slík lýsigögn um útgáfuna þína.
  2. Nú ber hver dráttarbeiðni á byggingu saman fjölda viðvarana sem hún fær við fjöldann í núverandi útgáfu. Ef PR leiðir til hækkunar á þessum fjölda, þá fer kóðinn ekki framhjá gæðahliðinu í kyrrstöðugreiningu. Ef viðvörunum fækkar eða breytist ekki, þá gengur það yfir.
  3. Í næstu útgáfu verður endurreiknaður fjöldi viðvarana skrifaður aftur í lýsigögn útgáfunnar.

Svo smátt og smátt, en jafnt og þétt (eins og með skralli), mun fjöldi viðvarana hafa tilhneigingu til að núll. Auðvitað er hægt að blekkja kerfið með því að koma með nýja viðvörun, en leiðrétta aðra. Þetta er eðlilegt, vegna þess að til lengri tíma litið gefur það niðurstöðuna: viðvaranir eru lagaðar, að jafnaði, ekki ein af annarri, heldur strax af hópi af ákveðinni tegund, og allar viðvaranir sem auðvelt er að útrýma eru fljótt eytt.

Þetta línurit sýnir heildarfjölda Checkstyle viðvarana fyrir sex mánaða notkun slíks „skralla“ eitt af opnum uppspretta verkefnum okkar. Viðvörunum hefur fækkað um stærðargráðu og það gerðist af sjálfu sér samhliða þróun vörunnar!

Innleiða truflanir greiningu í ferlið, frekar en að leita að villum með því

Ég nota breytta útgáfu af þessari aðferð, tel viðvaranir sérstaklega eftir verkeiningum og greiningartóli, sem leiðir til YAML skrá með samsetningarlýsigögnum sem líta einhvern veginn svona út:

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

Í hvaða háþróuðu CI kerfi sem er er hægt að innleiða skrall fyrir hvaða truflanir sem eru til greiningar án þess að treysta á viðbætur og verkfæri þriðja aðila. Hver greiningartæki framleiðir skýrslu sína á einföldu texta- eða XML-sniði sem auðvelt er að flokka. Það er eftir að skrá aðeins nauðsynlega rökfræði í CI handritinu. Þú getur séð hvernig þetta er útfært í opnum uppspretta verkefnum okkar sem byggjast á Jenkins og Artifactory, þú getur hér eða hér. Bæði dæmin eru háð bókasafni ratchetlib: aðferð countWarnings() telur xml merki í skrám sem eru búnar til af Checkstyle og Spotbugs á venjulegan hátt, og compareWarningMaps() útfærir sömu skrallann og kastar villu þegar fjöldi viðvarana í einhverjum af flokkunum hækkar.

Áhugaverð ratchet útfærsla er möguleg fyrir stafsetningargreiningu á athugasemdum, bókstaflegum texta og skjölum með aspell. Eins og þú veist þá eru ekki öll orð sem eru óþekkt í hefðbundinni orðabók röng þegar stafsetning er skoðuð, þeim er hægt að bæta við notendaorðabókina. Ef þú gerir notandaorðabókina að hluta af frumkóða verkefnisins, þá er hægt að setja stafsetningargæðahliðið á eftirfarandi hátt: aspell framkvæmd með stöðluðum og notendaorðabók ætti ekki finna engar stafsetningarvillur.

Um mikilvægi þess að laga greiningarútgáfuna

Að lokum skal tekið fram eftirfarandi: sama hvernig þú innleiðir greininguna í afhendingarleiðsluna þína, þá verður að laga útgáfu greiningartækisins. Ef þú leyfir greiningartækinu að uppfæra sjálfkrafa, þá geta nýir gallar „komið fram“ þegar þú byggir næstu dráttarbeiðni sem tengjast ekki kóðabreytingum, en tengjast því að nýja greiningartækið getur einfaldlega fundið fleiri galla - og þetta mun brjóta ferlið við að samþykkja dráttarbeiðnir. Uppfærsla á greiningartækinu ætti að vera meðvituð aðgerð. Hins vegar er erfitt að laga útgáfu hvers samsetningarhluta almennt nauðsynleg krafa og efni fyrir sérstaka umræðu.

Niðurstöður

  • Stöðug greining mun ekki finna villur fyrir þig og mun ekki bæta gæði vöru þinnar vegna eins forrits. Einu jákvæðu áhrifin á gæði er stöðug notkun þess meðan á afhendingu stendur.
  • Að finna villur er alls ekki aðalverkefni greiningar, langflestar gagnlegar aðgerðir eru tiltækar í opnum hugbúnaði.
  • Innleiða gæðahlið byggð á niðurstöðum kyrrstöðugreiningar á fyrsta stigi afhendingarleiðslunnar, með því að nota skrall fyrir eldri kóða.

tilvísanir

  1. Stöðug Afhending
  2. A. Kudryavtsev: Forritagreining: hvernig á að skilja að þú ert góður forritari skýrslu um mismunandi aðferðir við kóðagreiningu (ekki aðeins truflanir!)

Heimild: www.habr.com

Bæta við athugasemd