I vÄrt arbeid bruker vi aktivt plattformen SonarQube for Ä opprettholde kodekvalitet pÄ hÞyt nivÄ. Under integreringen av et prosjekt skrevet i VueJs+Typescript, oppstod det problemer. Derfor vil jeg gjerne forklare mer detaljert hvordan vi klarte Ä lÞse dem.

I denne artikkelen handler det, som nevnt tidligere, om plattformen SonarQube. Litt teori â hva det egentlig er, for de som hĂžrer om det for fĂžrste gang:
SonarQube (tidligere Sonar) â er en plattform med Ă„pen kildekode for kontinuerlig analyse (eng. continuous inspection) og mĂ„ling av kodekvaliteten.
Den stÞtter kodeanalyse og feiloppdagelse i henhold til reglene for programmeringsstandardene MISRA C, MISRA C++, MITRE/CWE og CERT Secure Coding Standards. Den kan ogsÄ gjenkjenne feil fra OWASP Top-10 og CWE/SANS Top-25 liste over programmeringsfeil.
Selv om plattformen bruker ulike ferdige verktĂžy, komprimerer SonarQube resultatene til et samlet informasjonspanel (eng. dashboard), og fĂžrer en historikk over kjĂžringer, noe som gir oss muligheten til Ă„ se den generelle trenden i endringene av programvarekvalitet gjennom utviklingen.
Mer informasjon kan finnes pÄ
Det stĂžttes et stort antall programmeringssprĂ„k. IfĂžlge informasjonen fra lenken ovenfor â er det mer enn 25 sprĂ„k. For Ă„ stĂžtte et spesifikt sprĂ„k mĂ„ den aktuelle pluginnen installeres. Community-versjonen inkluderer en plugin for Ă„ jobbe med Javascript (inkludert typesŃript), selv om det stĂ„r noe annet i wikin. Dette Javascript stĂžttes av pluginnen SonarJS, og for Typescript SonarTS henholdsvis.
For Ă„ sende dekning data brukes den offisielle klienten sonarqube-scanner, som, med innstillinger fra config-filen, sender disse dataene til serveren SonarQube for videre konsolidering og aggregasjon.
For Javascript det finnes . SĂ„, la oss begynne med steg-for-steg implementasjonen av SonarQube i Vue-prosjektet som bruker Typescript.
For Ă„ sette opp serveren vil vi bruke SonarQube sonar.yaml docker-compose.
version: '1' services: simplesample-sonar: image: sonarqube:lts ports: - 9001:9000 - 9092:9092 network_mode: bridge:
Oppstart:docker-compose -f sonar.yml up
Etter dettevil vĂŠre tilgjengelig pĂ„ adressen â SonarQube SĂ„ langt finnes det ingen prosjekter, og det er berettiget. Vi skal rette opp i denne situasjonen. Jeg har basert det pĂ„ det offisielle eksempelprosjektet for .

VueJS+TS+Jest . La oss klone det:git clone https://github.com/vuejs/vue-test-utils-typescript-example.git
FÞrst mÄ vi installere klientenFÞrst mÄ vi installere klienten SonarQube, som kalles sonar-scanner, for npm har en omsluttende kode:
yarn add sonarqube-scannerOg vi legger umiddelbart til kommandoen i scripts for Ă„ jobbe med det.
package.json:
{
âŠ
scripts: {
...
"sonar": "sonar-scanner"
...
},
âŠ
}Deretter, for at skanneren skal fungere, mÄ prosjektinnstillingene angis i en spesiell fil. La oss begynne med det grunnleggende.
sonar-project.properties:
sonar.host.url=http://localhost:9001
sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Test Application (VueJS+TS)
sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests/**/*
sonar.sourceEncoding=UTF-8- sonar.host.url â adressen Sonarâa;
- sonar.projectKey â den unike prosjektidentifikatoren pĂ„ serveren Sonarâa;
- sonar.projectName â navnet pĂ„ prosjektet, som kan endres nĂ„r som helst, ettersom prosjektidentifikasjonen skjer via projectKey;
- sonar.sources â mappen med kildefiler, som vanligvis er src, men kan vĂŠre hva som helst. Denne mappen angis i forhold til rotmappen, som er mappen hvor skanneren kjĂžres fra;
- sonar.tests â parameteret som henger sammen med det forrige. Dette er mappen der testene befinner seg. I dette prosjektet finnes det ingen slik mappe, og testen ligger ved siden av den testede komponenten i mappen âtestâ, sĂ„ vi bortser fra det for nĂ„ og bruker det neste parameteret;
- sonar.test.inclusions â banen for tester med bruk av et mĂžnster, kan ha flere elementer som er adskilt med komma;
- sonar.sourceEncoding â kodingen for kildefilene.
For den fĂžrste kjĂžringen av skanneren er alt klart, bortsett fra den viktigste forberedende handlingen: Ă„ starte selve testmotoren for Ă„ generere informasjon om dekning, som skanneren senere vil bruke.
Men for dette mĂ„ testmotoren konfigureres til Ă„ generere denne informasjonen. I dette prosjektet er testmotoren â Jest. Og innstillingene hans ligger i den relevante delen av filen. package.json.
La oss legge til disse innstillingene:
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*d.*",
"!src/**/*__tests__*"
],Det vil si at vi setter flagget for behovet for Ă„ beregne dekning og kilden (sammen med unntakene) som dekningen vil bli dannet ut ifra.
NĂ„ kjĂžrer vi testen:
yarn testVi ser fĂžlgende:

Ă rsaken er at det ikke er noe egentlig kode i komponenten. La oss fikse dette.
HelloWorld.vue:
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...Dette vil vĂŠre tilstrekkelig for Ă„ beregne dekning.
Etter Ä ha kjÞrt testen pÄ nytt, vil vi bekrefte dette:

PĂ„ skjermen skal vi se informasjon om dekning, og i prosjektmappen vil det bli opprettet en mappe dekning med informasjon om testdekning i et universelt format LCOV (LTP GCOV-utvidelse).
Gcov â et frittstĂ„ende verktĂžy for Ă„ undersĂžke kode-dekning. Gcov genererer nĂžyaktige antall kjĂžringer for hver setning i programmet og lar deg legge til merknader til kildekoden. Gcov fĂžlger med som et standardverktĂžy i GCC-pakken.
Lcov â et grafisk grensesnitt for gcov. Det samler gcov-filer for flere kildefiler og genererer et sett med HTML-sider med kode og dekning informasjon. Det genereres ogsĂ„ sider for Ă„ forenkle navigasjonen. Lcov stĂžtter dekning av linjer, funksjoner og forgreninger.
Etter at testene er fullfĂžrt, vil informasjonen om dekning befinne seg i coverage/lcov.info.
Vi mÄ si Sonarhvor den skal hentes fra. Derfor legger vi til fÞlgende linjer i konfigurasjonsfilen. Men det er et poeng: prosjektene kan vÊre flersprÄklige, det vil si at det i mappen src befinner seg kilder for flere programmeringssprÄk og tilknytningen til et spesifikt sprÄk og bruken av det spesifikke pluginet bestemmes av dets utvidelse. Og informasjon om dekning kan lagres pÄ forskjellige steder for forskjellige programmeringssprÄk, sÄ derfor er det et eget seksjon for innstilling for hvert sprÄk. VÄrt prosjekt bruker Typescript, sÄ vi trenger en innstillingsseksjon spesielt for det:
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.infoAlt er klart for fÞrste kjÞring av skanneren. Jeg vil gjerne pÄpeke at prosjektet i Sonarautomatiskt opprettes ved fÞrste kjÞring av skanneren for dette prosjektet. Ved pÄfÞlgende ganger vil informasjonen allerede bli akkumulert, slik at vi kan se dynamikken i endringene i prosjektparameterne over tid.
SĂ„, la oss bruke kommandoen som ble laget tidligere i package.json:
yarn run sonar Merk: du kan ogsÄ bruke parameteren -X for mer detaljert logging.
Hvis skanneren ble kjÞrt for fÞrste gang, vil den fÞrst laste ned binÊren for skanneren. Etter det starter den og begynner Ä skanne serveren Sonarfor installerte plugins, samtidig som den beregner stÞttede sprÄk. OgsÄ ulike andre parametere for dens drift lastes ned: kvalitetsprofiler, aktive regler, metrikkrepository, serverregler.


Merk: Vi vil ikke gÄ nÊrmere inn pÄ dem i denne artikkelen, men man kan alltid ta kontakt med offisielle kilder.
Videre begynner analysen av mappen src for Ä sjekke om det finnes kildefiler for alle (med mindre en bestemt programmeringssprÄk er spesifisert) stÞttede programmeringssprÄk, med pÄfÞlgende indeksering av dem.

Deretter kommer andre ulike analyser, som vi ikke fokuserer pÄ i denne artikkelen (for eksempel som: linting, identifisering av kodeduplisering osv.).
PĂ„ slutten av skannerens arbeid skjer det en aggregasjon av all innsamlet informasjon, arkivering og sending til serveren.
Etter dette kan vi se hva vi fikk i webgrensesnittet:

Som vi ser, har vi fÄtt noe, og det viser til og med en viss dekning, men den samsvarer ikke med vÄr Jest-rapport.
La oss finde ut av dette. Vi ser nÊrmere pÄ prosjektet, klikker pÄ dekningens verdi, og "gÄr inn" i den detaljerte rapporten om filene:

Her ser vi, i tillegg til den primÊre filen vi undersÞker, HelloWorld.vue, finnes ogsÄ filen main.ts, som Þdelegger hele dekningen. Men hvordan kan det vÊre, vi ekskluderte den fra dekningen. Ja, det er riktig, men det ble gjort pÄ nivÄet Jest, men scanner indekserte den, sÄ den havnet i beregningene.
La oss fikse dette:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...Det er verdt Ä presisere: utover de mappene som er angitt i denne parameteren, legges ogsÄ alle mapper som er oppfÞrt i parameteren sonar.test.inclusions.
Etter Ă„ ha kjĂžrt scanneren ser vi allerede korrekt informasjon:


La oss gĂ„ gjennom neste punkt â Kvalitetsprofiler.Jeg nevnte tidligere at stĂžtte for flere programmeringssprĂ„k samtidig eksisterer. Dette er akkurat det vi observerer. Men vi vet at prosjektet er skrevet i SonarTS , sĂ„ hvorfor belaste skanneren med unĂždvendige manipulasjoner og sjekker. SprĂ„ket for analysen skal vi definere ved Ă„ legge til en annen parameter i konfigurasjonsfilen: Sonar... sonar.language=ts ...
sonar-project.properties:
La oss kjĂžre scanneren igjen og se resultatet:Dekningen forsvant helt.

Hvis vi ser i loggen til skanneren, kan vi se fĂžlgende linje:
Det vil si at filene i prosjektet vÄrt bare ikke ble indeksert.
![]()
Situasjonen er som fĂžlger: den offisielle stĂžtten for
VueJs finnes i pluginet , som svarer til SonarJSMen denne stĂžtten finnes ikke i pluginet Javascript.

, noe som det er opprettet en offisiell ticket om i bug-tracker SonarTS for , sÄ hvorfor belaste skanneren med unÞdvendige manipulasjoner og sjekker. SprÄket for analysen skal vi definere ved Ä legge til en annen parameter i konfigurasjonsfilen. Sonar... sonar.language=ts ...
Her er noen svar fra en av representantene fra utviklerne av SonarQube som bekrefter dette faktum.


Men alt fungerte jo for oss, vil du protestere. Ja, det stemmer, la oss prĂžve litt âĂ„ hackeâ.
Hvis det er stĂžtte .vue-filer Sonarâen, sĂ„ la oss prĂžve Ă„ si til den at den skal vurdere dem som Typescript.
La oss legge til en parameter:
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...La oss kjĂžre skanneren:

Og, voila, alt har kommet tilbake til det normale, med bare ett profil for Typescript. SĂ„, vi klarte Ă„ lĂžse problemet med stĂžtten for VueJs+TS for SonarQube.
La oss prÞve Ä gÄ videre og forbedre informasjonen om dekning litt.
Hva har vi gjort sÄ langt:
- lagt til prosjektet Sonar-skanneren;
- konfigurert Jest for Ă„ generere informasjon om dekning;
- konfigurert Sonar-skanneren;
- lĂžst problemet med stĂžtten til .vue-filer + Typescript.
I tillegg til testdekning er det andre interessante kriterier for programkvalitet, som f.eks. kode duplikering og antall linjer (som brukes i beregningen av koeffisienter relatert til kodekompleksitet) i prosjektet.
I den nÄvÊrende implementeringen av pluginen for arbeid med , sÄ hvorfor belaste skanneren med unÞdvendige manipulasjoner og sjekker. SprÄket for analysen skal vi definere ved Ä legge til en annen parameter i konfigurasjonsfilen (SonarTS) vil ikke fungere CPD (Copy Paste Detector) og telling av linjer med kode .vue-filer.
For Ä skape en syntetisk situasjon for kode duplikering, bare dupliser en komponentfil med et annet navn, og legg til en dummy-funksjon i koden og dupliser den med et annet navn. For Ä sjekke duplikasjonen som i main.ts , sÄ vel som i .vue.ts -filer. main.ts:
... function name(params:string): void { console.log(params); } ...
For dette mÄ vi midlertidig kommentere ut konfigurasjonslinjen:La oss starte skanneren pÄ nytt sammen med testing:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...yarn test && yarn run sonar
SelvfÞlgelig vil dekningen falle, men for nÄ er vi ikke interessert i dette.NÄr det gjelder duplikering av linjer med kode, vil vi se:
For Ă„ kontrollere, la oss bruke

CPD -verktĂžyet âjscpd npx jscpd src:
For linjer med kode:
Dette kan lĂžses i fremtidige versjoner av pluginene

SonarJS(TS) . Jeg vil pÄpeke at de gradvis begynner Ä slÄ sammen disse to pluginene til én, noe som, tror jeg, er riktig. SonarJSNÄ vil jeg gjerne se pÄ muligheten for Ä forbedre informasjonen om dekning.
SĂ„ langt ser vi testdekning i prosent i hele prosjektet, og for filene spesielt. Men det er mulighet for Ă„ utvide dette tiltaket med informasjon om antall
unit -tester i prosjektet, samt pÄ tvers av filene.Det finnes et bibliotek som kan
-rapporten konvertere til format for Jestgeneric test data Sonar... sonar.language=ts ...
La oss installere dette biblioteket i prosjektet vĂ„rt: â .
La oss installere dette biblioteket i prosjektet vÄrt:
yarn add jest-sonar-reporterOg vi legger det til i konfigurasjonen Jest:
package.json:
âŠ
"testResultsProcessor": "jest-sonar-reporter"
âŠNĂ„ skal vi kjĂžre testen:
yarn testEtter det vil det bli opprettet en fil i rotmappen av prosjektet test-report.xml.
Vi bruker det i konfigurasjonen Sonar... sonar.language=ts ...
sonar-project.properties:
âŠ
sonar.testExecutionReportPaths=test-report.xml
âŠOg vi starter skanneren pĂ„ nytt:
yarn run sonarLa oss se hva som har endret seg i grensesnittet Sonar... sonar.language=ts ...

Og ingenting har endret seg. Faktisk, Sonar vurderer ikke filene beskrevet i Jest-rapporten som filer -tester i prosjektet, samt pÄ tvers av filene.-tester. For Ä lÞse denne situasjonen bruker vi konfigurasjonsparameteren Sonar sonar.tests, der vi eksplisitt angir mapper med tester (for tiden har vi bare en):
sonar-project.properties:
âŠ
sonar.tests=src\/components\/__tests__
âŠVi starter skanneren pĂ„ nytt:
yarn run sonarLa oss se hva som har endret seg i grensesnittet:

NÄ har vi sett antall vÄre -tester i prosjektet, samt pÄ tvers av filene.-tester og, ved Ä klikke inn, kan vi se fordelingen av dette tallet pÄ prosjektfilene:

Konklusjon
SÄ, vi har sett pÄ et verktÞy for kontinuerlig analyse SonarQube. Vi integrerte prosjektet, som ble skrevet pÄ VueJs+TS. Vi lÞste noen kompatibilitetsproblemer. Vi Þkte informasjonen i indikatoren for testdekning. I denne artikkelen har vi sett pÄ bare ett av kvalitetskriteriene (kanskje et av de viktigste), men SonarQube stÞtter ogsÄ andre kvalitetskriterier, inkludert sikkerhetstesting. Men ikke alle disse funksjonene er fullt tilgjengelige i community-versjonen. En av de interessante og nyttige mulighetene er integrasjoner SonarQube med forskjellige kodebehandlingssystemer, som GitLab og BitBucket. For Ä unngÄ merge pull(merge) requesttil hovedgreinen av depotet ved degradert dekning. Men det er en helt annen artikkel.
PS: Alt som er beskrevet i artikkelen i form av kode er tilgjengelig i .
Kun registrerte brukere kan delta i undersÞkelsen. , vÊr sÄ snill.
Bruker du SonarQube-plattformen:
26,3%Ja5
15,8%Nei3
15,8%Har hĂžrt om denne plattformen og vil bruke den3
10,5%Har hĂžrt om denne plattformen og vil ikke bruke den2
0,0%Bruker en annen plattform0
31,6%HĂžrer om den for fĂžrste gang6
19 brukere stemte. 3 brukere avholdt seg.
Kilde: habr.com
