Мүчүлүштүктөрдү табуу үчүн колдонуунун ордуна, процесске статикалык анализди киргизиңиз

Мени бул макаланы жазууга менин көңүлүмдү көбүрөөк буруп жаткан статикалык анализ боюнча материалдардын көптүгү түрткү болду. Биринчиден, бул PVS-studio блогу, бул ачык булак долбоорлорунда алардын куралы тарабынан табылган каталарды карап чыгуунун жардамы менен өзүн Habréде жигердүү жарнамалайт. Жакында PVS-студиясы ишке ашырылды Java колдоосу, жана, албетте, IntelliJ IDEA иштеп чыгуучулары, анын орнотулган анализатору, балким, бүгүнкү күндө Java үчүн эң өнүккөн. алыс кала алган жок.

Мындай сын-пикирлерди окуп жатып, сиз сыйкырдуу эликсир жөнүндө сөз кылып жатканыбызды сезесиз: баскычты басыңыз, бул жерде - көз алдыңыздагы кемчиликтердин тизмеси. Анализаторлор жакшырган сайын каталар автоматтык түрдө табылып, бул роботтор сканерлеген өнүмдөр биз тараптан эч кандай күч-аракет жумшабастан жакшырып, жакшырып баратат окшойт.

Бирок сыйкырдуу эликсирлер жок. Мен "бул жерде биздин робот таба ала турган нерселер" сыяктуу посттордо айтылбаган нерселер жөнүндө айткым келет: анализаторлор эмне кыла албайт, программалык камсыздоону жеткирүү процессинде алардын чыныгы ролу жана орду кандай жана аларды кантип туура ишке ашыруу керек .

Мүчүлүштүктөрдү табуу үчүн колдонуунун ордуна, процесске статикалык анализди киргизиңиз
Ратчет (булак: Wikipedia).

Статикалык анализаторлор эч качан кыла албайт

Практикалык көз караштан алганда булак кодун талдоо деген эмне? Биз кээ бир баштапкы кодду киргизүү жана чыгаруу катары кыска убакыттын ичинде (тесттерге караганда кыскараак) беребиз, биз системабыз жөнүндө кээ бир маалыматты алабыз. Негизги жана математикалык жактан чечилгис чектөө бул жол менен биз бир кыйла тар маалымат классын ала алабыз.

Статикалык анализдин жардамы менен чечилбеген маселенин эң белгилүү мисалы болуп саналат өчүрүү маселеси: Бул программанын баштапкы кодунан анын циклин же чектүү убакытта бүтөөрүн аныктай ала турган жалпы алгоритмди иштеп чыгуу мүмкүн эмес экенин далилдеген теорема. Бул теореманын узартылышы болуп саналат Райс теоремасы, анда эсептелүүчү функциялардын ар кандай тривиалдык эмес касиеттери үчүн, ыктыярдуу программа ушундай касиетке ээ функцияны баалай тургандыгын аныктоо алгоритмдик жактан чечилгис маселе болуп саналат деп айтылат. Мисалы, анализдеп жаткан программа, айталы, бүтүн сандын квадратын эсептеген алгоритмдин ишке ашырылышы экендигин кандайдыр бир баштапкы коддон аныктай ала турган анализаторду жазуу мүмкүн эмес.

Ошентип, статикалык анализаторлордун функционалдуулугу чечилбес чектөөлөргө ээ. Статикалык анализатор эч качан бардык учурларда, мисалы, нөлдүн маанисин берген тилдерде "нөлдүк көрсөткүчтүн өзгөчөлүгүнүн" пайда болушун же бардык учурларда "болушун аныктай албайт" атрибут табылган жок" динамикалык терилген тилдерде. Эң өнүккөн статикалык анализатор жасай ала турган нерсе - бул өзгөчө учурларды бөлүп көрсөтүү, алардын саны, сиздин баштапкы кодуңуздагы мүмкүн болгон көйгөйлөрдүн ичинен, апыртмасыз, океандагы тамчы.

Статикалык талдоо мүчүлүштүктөрдү табуу жөнүндө эмес

Жогоруда айтылгандардан тыянак келип чыгат: статикалык талдоо программадагы кемчиликтердин санын азайтуучу каражат эмес. Мен мындай деп айткым келет: сиздин долбооруңузга биринчи жолу колдонулганда, ал коддон "кызыктуу" жерлерди табат, бирок, балким, программаңыздын сапатына таасир этүүчү кемчиликтерди таппай калат.

Анализаторлор тарабынан автоматтык түрдө табылган кемчиликтердин мисалдары таасирдүү, бирок бул мисалдар чоң коддук базалардын чоң топтомун сканерлөө аркылуу табылганын унутпашыбыз керек. Ушул эле принцип боюнча, көптөгөн аккаунттарда бир нече жөнөкөй сырсөздөрдү сынап көрүү мүмкүнчүлүгү бар хакерлер акыры жөнөкөй сырсөзү бар аккаунттарды табышат.

Бул статикалык анализди колдонууга болбойт дегенди билдиреби? Албетте жок! Жана дал ушул себептен улам, ар бир жаңы сырсөздү текшерип, анын "жөнөкөй" сырсөздөрдүн стоп тизмесине киргизилгендигин текшерүү керек.

Статикалык талдоо мүчүлүштүктөрдү табууга караганда көбүрөөк нерсе

Чындыгында, талдоо жолу менен иш жүзүндө чечилген көйгөйлөр алда канча кеңири. Анткени, жалпысынан алганда, статикалык талдоо бул ишке киргизилгенге чейин жүргүзүлгөн баштапкы коддордун ар кандай текшерүү болуп саналат. Бул жерде сиз кыла ала турган кээ бир нерселер бар:

  • Сөздүн кеңири маанисинде коддоо стилин текшерүү. Бул форматтоону текшерүүнү, бош/кошумча кашааларды колдонууну издөөнү, сызыктардын саны/методдун цикломатикалык татаалдыгы сыяктуу метрикалар боюнча босоголорду коюуну ж.б. - коддун окулушуна жана туруктуулугуна тоскоол болгон бардык нерселерди камтыйт. Javaда мындай курал Checkstyle, Pythonдо - flake8. Бул класстын программалары адатта "линтер" деп аталат.
  • Аткарылуучу кодду гана талдоо мүмкүн эмес. JSON, YAML, XML, .properties сыяктуу ресурстук файлдардын жарактуулугу автоматтык түрдө текшерилиши мүмкүн (жана керек!). Акыры, JSON структурасы айрым жупташтырылбаган тырмакчалардан улам бузулганын автоматтык Pull Request текшерүүсүнүн алгачкы этабында сыноону аткарууга же иштөө убактысына караганда билип алган жакшыбы? Тиешелүү куралдар бар: мис. YAMLlint, JSONLint.
  • Компиляция (же динамикалык программалоо тилдери үчүн талдоо) да статикалык анализдин бир түрү болуп саналат. Жалпысынан алганда, компиляторлор баштапкы коддун сапаты менен көйгөйлөрдү көрсөткөн эскертүүлөрдү чыгара алышат жана аларды четке кагууга болбойт.
  • Кээде компиляция жөн гана аткарылуучу кодду компиляциялоо эмес. Мисалы, форматтагы документтериңиз болсо AsciiDoctor, андан кийин аны HTML/PDFге айландыруу учурунда AsciiDoctor иштеткич (Maven плагини) эскертүүлөрдү бере алат, мисалы, бузулган ички шилтемелер жөнүндө. Жана бул документтерди өзгөртүү менен тартуу өтүнүчүн кабыл албоо үчүн жакшы себеп.
  • Орфографияны текшерүү да статикалык анализдин бир түрү болуп саналат. Утилита жазуу документтерде гана эмес, ошондой эле ар кандай программалоо тилдеринде, анын ичинде C/C++, Java жана Python тилдериндеги программалык баштапкы коддордо (комментарийлерде жана литералдарда) орфографияны текшере алат. Колдонуучу интерфейсиндеги же документтердеги орфографиялык ката да кемчилик!
  • Конфигурация тесттери (алар эмне экендиги жөнүндө - караңыз. бул и бул отчёттор), pytest сыяктуу бирдик тестинин иштөө убактысында аткарылса да, чындыгында статикалык анализдин бир түрү болуп саналат, анткени алар аткаруу учурунда баштапкы коддорду аткарышпайт.

Көрүнүп тургандай, бул тизмедеги мүчүлүштүктөрдү издөө эң аз маанилүү ролду ойнойт, ал эми калганынын бардыгы бекер ачык булак куралдарын колдонуу менен жеткиликтүү.

Долбооруңузда статикалык анализдин ушул түрлөрүнүн кайсынысын колдонушуңуз керек? Албетте, канчалык көп болсо, ошончолук жакшы! Эң негизгиси, аны туура ишке ашыруу, ал тууралуу мындан ары да талкууланат.

Көп баскычтуу чыпка катары жеткирүү түтүгү жана анын биринчи этабы катары статикалык талдоо

Үзгүлтүксүз интеграциянын классикалык метафорасы бул булак кодун өзгөртүүдөн өндүрүшкө жеткирүүгө чейинки өзгөрүүлөрдүн агымы аркылуу өтүүчү түтүк. Бул куурдагы этаптардын стандарттык ырааттуулугу төмөнкүдөй көрүнөт:

  1. статикалык талдоо
  2. компиляция
  3. бирдик сыноолор
  4. интеграциялык тесттер
  5. UI тесттери
  6. кол менен текшерүү

Түтүк өткөргүчтүн N-баскычында четке кагылган өзгөртүүлөр N+1 баскычына өткөрүлбөйт.

Эмне үчүн так ушул жол менен башкасы эмес? Түтүктүн сыноо бөлүгүндө тестирлөөчүлөр белгилүү сыноо пирамидасын тааныйт.

Мүчүлүштүктөрдү табуу үчүн колдонуунун ордуна, процесске статикалык анализди киргизиңиз
Сыноо пирамидасы. Булак: макала Мартин Фаулер.

Бул пирамиданын ылдый жагында жазууга оңой, аткарылышы тез жана ийгиликсиз болуу тенденциясы жок тесттер бар. Ошондуктан, алар көбүрөөк болушу керек, алар көбүрөөк кодду камтышы керек жана биринчи кезекте аткарылышы керек. Пирамиданын башында, тескерисинче, интеграция жана UI тесттеринин саны зарыл болгон минимумга чейин азайтылышы керек. Бул чынжырдагы адам эң кымбат, жай жана ишенимсиз ресурс болуп саналат, ошондуктан ал эң аягында турат жана мурунку этаптар эч кандай кемчиликтерди таппаса гана ишти аткарат. Бирок, сыноого түздөн-түз байланышпаган бөлүктөрдө түтүктөрдү куруу үчүн да ошол эле принциптер колдонулат!

Мен көп баскычтуу суу чыпкалоо системасы түрүндө окшоштук сунуш кылгым келет. Кир суу (кемчиликтери менен өзгөрөт) кирүүгө берилет, чыгууда биз бардык керексиз булгоочу заттар жок болгон таза сууну алышыбыз керек.

Мүчүлүштүктөрдү табуу үчүн колдонуунун ордуна, процесске статикалык анализди киргизиңиз
Көп баскычтуу чыпка. Булак: Wikimedia Commons

Белгилүү болгондой, тазалоочу чыпкалар ар бир кийинки каскад булгоочу заттардын барган сайын майда бөлүгүн чыпкалай тургандай кылып жасалган. Ошол эле учурда, одоно тазалоо каскаддары жогорку өткөрүү жөндөмдүүлүгүнө ээ жана арзаныраак. Биздин аналогияда, бул киргизүү сапаты дарбазалары тезирээк, баштоо үчүн аз күч-аракетти талап кылат жана эксплуатацияда өздөрүн жөнөкөйлөштүрөт - жана бул алар курулган ырааттуулук. Статикалык анализдин ролу, биз азыр түшүнгөндөй, эң одоно кемчиликтерди гана жок кылууга жөндөмдүү, фильтрлер каскадынын эң башталышындагы “ылай” торунун ролу.

Статикалык анализдин өзү эле акыркы продукциянын сапатын жакшырта албайт, «ылай чыпкасы» сууну ичүүгө жарабайт. Ошондой болсо да, куурдун башка элементтери менен бирге, анын мааниси айкын көрүнүп турат. Көп баскычтуу чыпкада чыгаруу этаптары киргизүү этаптары жасаган нерселердин баарын басып алууга жөндөмдүү болсо да, киргизүү этаптары жок эле майда тазалоо этаптары менен жасоо аракети кандай натыйжаларга алып келери анык.

"Баткак капкандын" максаты - кийинки каскаддарды өтө одоно кемчиликтерди кармоодон бошотуу. Мисалы, жок дегенде, кодду карап жаткан адам туура эмес форматталган код жана белгиленген коддоо стандарттарынын бузулушу (кошумча кашаалар же өтө терең салынган бутактар ​​сыяктуу) менен алаксып калбашы керек. NPE сыяктуу мүчүлүштүктөр бирдик тесттери аркылуу кармалышы керек, бирок тестирлөөгө чейин анализатор ката болушу мүмкүн экенин көрсөтсө, бул аны оңдоону кыйла тездетет.

Мен эмне үчүн статикалык талдоо маал-маалы менен колдонулса, буюмдун сапатын жакшыртпасын жана одоно кемчиликтер менен өзгөрүүлөрдү чыпкалоо үчүн дайыма колдонулушу керектиги түшүнүктүү деп эсептейм. Статикалык анализаторду колдонуу сиздин продукцияңыздын сапатын жакшыртабы деген суроо болжол менен “Кирги көлмөдөн алынган суу дуршлагдан өткөрүлсө ичүүчү сапаты жакшырабы?” деген суроого тете.

Мурдагы долбоорго ишке ашыруу

Маанилүү практикалык суроо: “сапат дарбазасы” катары үзгүлтүксүз интеграция процессине статикалык анализди кантип киргизүү керек? Автоматтык сыноолордо бардыгы ачык-айкын көрүнүп турат: сыноолордун комплекси бар, алардын биринин да аткарылбай калышы монтаж сапат дарбазасынан өткөн жок деп ишенүүгө жетиштүү негиз болуп саналат. Статикалык анализдин жыйынтыгы боюнча дарбазаны ушундай эле жол менен орнотуу аракети ишке ашпай калат: эски коддо талдоо эскертүүлөрү өтө көп, сиз аларды толугу менен этибарга алгыңыз келбейт, бирок продуктуну жөнөтүүнү токтотуу да мүмкүн эмес. анткени ал анализатор эскертүүлөрүн камтыйт.

Биринчи жолу колдонулганда, анализатор ар кандай долбоор боюнча көп сандагы эскертүүлөрдү чыгарат, алардын басымдуу көпчүлүгү буюмдун туура иштешине байланыштуу эмес. Бул комментарийлердин бардыгын бир эле учурда оңдоо мүмкүн эмес жана көбүнүн кереги жок. Анткени, биз бүтүндөй биздин продукт статикалык анализди киргизгенге чейин эле иштей турганын билебиз!

Натыйжада, көпчүлүк статикалык анализди маал-маалы менен колдонуу менен чектелет, же аны жөн гана чогултуу учурунда анализатордун отчету чыгарылганда маалымат режиминде гана колдонушат. Бул эч кандай анализдин жоктугуна барабар, анткени бизде мурунтан эле көптөгөн эскертүүлөр бар болсо, кодду өзгөртүүдө башкасынын пайда болушу (канчалык олуттуу болбосун) байкалбай калат.

Сапаттуу дарбазаларды киргизүүнүн төмөнкү ыкмалары белгилүү:

  • Эскертүүлөрдүн жалпы санына чек коюу же эскертүүлөрдүн санын коддун саптарынын санына бөлүү. Бул начар иштейт, анткени мындай дарбаза жаңы кемчиликтери бар өзгөрүүлөрдү, алардын чегинен ашпаса, ээн-эркин өткөрүүгө мүмкүндүк берет.
  • Белгилүү бир учурда коддогу бардык эски эскертүүлөрдү этибарга албоо жана жаңы эскертүүлөр пайда болгондо куруудан баш тартуу. Бул функцияны PVS-studio жана кээ бир онлайн ресурстары, мисалы, Codacy камсыз кылат. Менде PVS-студияда иштөөгө мүмкүнчүлүгүм болгон жок, анткени Codacy менен болгон тажрыйбам боюнча, алардын негизги көйгөйү - бул "эски" жана "жаңы" ката деген эмне экенин аныктоо дайыма эле иштей бербеген татаал алгоритм. туура, өзгөчө файлдар катуу өзгөртүлгөн же аты өзгөртүлгөн болсо. Менин тажрыйбам боюнча, Codacy тартуу сурамындагы жаңы эскертүүлөрдү этибарга албай коюшу мүмкүн, ошол эле учурда берилген PRдын кодун өзгөртүүгө байланышпаган эскертүүлөрдөн улам тартуу өтүнүчүн өткөрбөй коюшу мүмкүн.
  • Менин оюмча, эң эффективдүү чечим бул китепте айтылган үзгүлтүксүз жеткирүү "чаптоо ыкмасы". Негизги идея статикалык талдоо эскертүүлөрүнүн саны ар бир релиздин менчиги болуп саналат жана эскертүүлөрдүн жалпы санын көбөйтпөгөн өзгөртүүлөргө гана уруксат берилет.

Ratchet

Ал мындай иштейт:

  1. Баштапкы этапта анализаторлор тапкан коддогу эскертүүлөрдүн санын чыгаруу жөнүндө метаберилиштерде жазуу жүргүзүлөт. Ошентип, сиз агымдын өйдө жагында курганыңызда, репозиторийиңиздин менеджери жөн гана "7.0.2 чыгарууну" эмес, "7.0.2 текшерүү стили эскертүүлөрүн камтыган 100500 чыгарууну" жазат. Эгер сиз өркүндөтүлгөн репозиторий башкаруучусун (мисалы, Artifactory) колдонсоңуз, релизиңиз жөнүндө мындай метаберилиштерди сактоо оңой.
  2. Эми ар бир тартуу өтүнүчү курулганда, натыйжадагы эскертүүлөрдүн санын учурдагы релиздеги эскертүүлөрдүн саны менен салыштырат. Эгерде PR бул сандын көбөйүшүнө алып келсе, анда код статикалык талдоо үчүн сапат дарбазасынан өтпөйт. Эгерде эскертүүлөрдүн саны азайса же өзгөрбөсө, анда ал өтөт.
  3. Кийинки чыгарылышта эскертүүлөрдүн кайра эсептелген саны релиз метаберилиштеринде кайрадан жазылат.

Ошентип, акырындык менен, бирок ырааттуу түрдө (мисалы, ратчет иштегенде), эскертүүлөрдүн саны нөлгө барабар болот. Албетте, жаңы эскертүү киргизип, бирок башка бирөөнүн эскертүүсүн оңдоо менен система алданышы мүмкүн. Бул нормалдуу көрүнүш, анткени узак аралыкта бул натыйжаларды берет: эскертүүлөр, эреже катары, жекече эмес, белгилүү бир түрдөгү бир топко түзүлөт жана бардык оңой алынып салынуучу эскертүүлөр тез арада жок кылынат.

Бул графикте мындай "ратчеттин" алты ай иштөөсү үчүн Checkstyle эскертүүлөрүнүн жалпы саны көрсөтүлгөн биздин OpenSource долбоорлорубуздун бири. Эскертүүлөрдүн саны чоңдуктун тартибине азайды жана бул табигый түрдө, продукцияны иштеп чыгуу менен катар эле болду!

Мүчүлүштүктөрдү табуу үчүн колдонуунун ордуна, процесске статикалык анализди киргизиңиз

Мен бул методдун өзгөртүлгөн версиясын колдоном, эскертүүлөрдү долбоордун модулу жана талдоо куралы боюнча өзүнчө эсептеп, натыйжада YAML файлын түзүү метадайындары төмөнкүдөй көрүнөт:

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

Ар кандай өнүккөн CI тутумунда ратчет плагиндерге жана үчүнчү тараптын куралдарына ишенбестен статикалык талдоо куралдары үчүн ишке ашырылышы мүмкүн. Ар бир анализатор өзүнүн отчетун талдоо оңой болгон жөнөкөй текст же XML форматында чыгарат. Болгону CI сценарийинде керектүү логиканы жазуу гана калды. Бул Jenkins жана Artifactory негизиндеги ачык булак долбоорлорубузда кантип ишке ашырылып жатканын көрө аласыз бул жерде же бул жерде. Эки мисал тең китепканадан көз каранды ratchetlib: ыкмасы countWarnings() Checkstyle жана Spotbugs тарабынан түзүлгөн файлдардагы xml тэгдерин кадимки жол менен эсептейт жана compareWarningMaps() категориялардын кайсы биринде эскертүүлөрдүн саны көбөйгөндө ката кетирип, ошол эле ратчетти ишке ашырат.

Комментарийлердин орфографиясын, текст литералдарын жана aspell аркылуу документтерди талдоо үчүн "ратчеттин" кызыктуу ишке ашырылышы мүмкүн. Белгилүү болгондой, орфографияны текшерүүдө стандарттык сөздүккө белгисиз сөздөрдүн баары эле туура эмес, аларды колдонуучунун сөздүгүнө кошууга болот. Эгер сиз ыңгайлаштырылган сөздүктү долбоордун баштапкы кодунун бир бөлүгүн жасасаңыз, анда орфографиялык сапат дарбазасы төмөнкүчө түзүлүшү мүмкүн: стандарттуу жана ыңгайлаштырылган сөздүк менен aspell иштетүү болбошу керек эч кандай орфографиялык каталарды табуу.

Анализатордун версиясын бекитүүнүн маанилүүлүгү жөнүндө

Жыйынтыктап айтканда, белгилей кетчү нерсе, сиз жеткирүү түтүкчөңүзгө анализди кантип киргизбеңиз, анализатордун версиясы бекитилиши керек. Эгерде сиз анализаторго өзүнөн-өзү жаңыртууга уруксат берсеңиз, анда кийинки тартуу өтүнүчүн чогултуп жатканда, коддун өзгөрүшүнө байланышпаган жаңы кемчиликтер "пайда болушу" мүмкүн, бирок жаңы анализатор жөн эле көбүрөөк кемчиликтерди таба алганына байланыштуу - жана бул тартуу сурамдарын кабыл алуу процессиңизди бузат. Анализаторду жаңылоо аң-сезимдүү иш-аракет болушу керек. Бирок, ар бир монтаждык компоненттин версиясын катуу бекитүү жалпысынан зарыл талап жана өзүнчө талкуулоо үчүн тема болуп саналат.

табылгалары

  • Статикалык талдоо сиз үчүн мүчүлүштүктөрдү таба албайт жана бир эле колдонуунун натыйжасында продуктуңуздун сапатын жакшыртпайт. Сапатка оң таасир этүүнү жеткирүү процессинде дайыма колдонуу аркылуу гана жетишүүгө болот.
  • Мүчүлүштүктөрдү табуу анализдин негизги милдети эмес; пайдалуу функциялардын басымдуу көпчүлүгү ачык булак куралдарында бар.
  • Жеткирүү түтүгүнүн эң биринчи этабында статикалык анализдин жыйынтыктарынын негизинде сапат дарбазаларын эски код үчүн "ратчет" аркылуу ишке ашырыңыз.

шилтемелер

  1. үзгүлтүксүз жеткирүү
  2. А.Кудрявцев: Программаны талдоо: жакшы программист экениңизди кантип түшүнсө болот код талдоо ар кандай ыкмалары боюнча отчет (статикалык гана эмес!)

Source: www.habr.com

Комментарий кошуу