Vi bruker plattformen aktivt i vårt arbeid soundQube for å opprettholde kodekvaliteten på et høyt nivå. Ved integrering av et av prosjektene skrevet inn VueJs+Typescript, oppsto det problemer. Derfor vil jeg gjerne fortelle deg mer detaljert hvordan vi klarte å løse dem.
I denne artikkelen vil vi snakke, som jeg skrev ovenfor, om SonarQube-plattformen. En liten teori - hva det er generelt, for de som hører om det for første gang:
soundQube (tidligere Sonar) er en åpen kildekode-plattform for kontinuerlig inspeksjon og måling av kodekvalitet.
Støtter kodeanalyse og feildeteksjon i henhold til reglene i programmeringsstandardene MISRA C, MISRA C++, MITER/CWE og CERT Secure Coding Standards. Den kan også gjenkjenne feil fra OWASP Topp 10 og CWE/SANS Topp 25 programmeringsfeillister.
Til tross for at plattformen bruker forskjellige ferdige verktøy, reduserer SonarQube resultatene til ett enkelt dashbord, og holder en historikk over kjøringer og lar deg dermed se den generelle trenden med endringer i programvarekvalitet under utvikling.
Flere detaljer finner du på
Et stort antall programmeringsspråk støttes. Ut fra informasjonen fra lenken ovenfor er dette mer enn 25 språk. For å støtte et spesifikt språk, må du installere riktig plugin. Fellesskapsversjonen inkluderer en plugin for å jobbe med Javascript (inkludert typeskrift), selv om wikien sier det motsatte. Bak Javascript plugin-svar SonarJS, for Typescript SonarTS henholdsvis.
Den offisielle klienten brukes til å sende dekningsinformasjon sonarqube-skanner, som ved hjelp av innstillingene fra config-fil, sender disse dataene til serveren soundQube for ytterligere konsolidering og aggregering.
For Javascript det er
For å distribuere en server soundQube la oss dra nytte Docker-komponere.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridge
Lansering:
docker-compose -f sonar.yml up
Deretter soundQube vil være tilgjengelig på:
Det er ingen prosjekter i den ennå, og det er rettferdig. Vi vil rette opp denne situasjonen. Jeg tok det offisielle eksempelprosjektet for VueJS+TS+Jest. La oss bøye det mot oss selv:
git clone https://github.com/vuejs/vue-test-utils-typescript-example.git
Først må vi installere klienten soundQube, som kalles sonar-skannertil NPM det er et omslag:
yarn add sonarqube-scanner
Og umiddelbart legg til kommandoen til skript å jobbe med det.
package.json:
{
…
scripts: {
...
"sonar": "sonar-scanner"
...
},
…
}
Deretter, for at skanneren skal fungere, må du angi prosjektinnstillingene i en spesiell fil. La oss starte 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 - adresse Sonar'EN;
- sonar.projectKey – unik prosjektidentifikator på serveren Sonar'EN;
- sonar.prosjektnavn – navnet, det kan endres når som helst, siden prosjektet er identifisert av prosjektnøkkel;
- sonar.kilder – mappe med kilder, vanligvis dette src, men kan være hva som helst. Denne mappen er satt i forhold til rotmappen, som er mappen som skanneren startes fra;
- sonar.tester – en parameter som går i takt med den forrige. Dette er mappen hvor testene ligger. I dette prosjektet er det ingen slik mappe, og testen ligger ved siden av komponenten som testes i mappen 'test', så vi vil ignorere det for nå og bruke neste parameter;
- sonar.test.inkluderinger – bane for tester med en maske, det kan være flere elementer oppført atskilt med komma;
- sonar.sourceEncoding – koding for kildefiler.
For den første lanseringen av skanneren er alt klart, bortsett fra hovedhandlingen foran: lansering av selve testmotoren, slik at den kan generere informasjon om dekningen, som skanneren senere vil bruke.
Men for å gjøre dette, må du konfigurere testmotoren til å generere denne informasjonen. I dette prosjektet er testmotoren det er. Og innstillingene er i den tilsvarende delen av filen pakke.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 selve flagget for behovet for å beregne dekning og kilden (sammen med unntak) som den skal dannes på grunnlag av.
La oss nå kjøre testen:
yarn test
Vi vil se følgende:
Årsaken er at det ikke er noen kode i selve 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 nok til å beregne dekning.
Etter å ha startet testen på nytt, vil vi sørge for dette:
På skjermen skal vi se informasjon om dekningen, og det opprettes en mappe i prosjektmappen dekning med informasjon om testdekning i et universelt format LCOV (LTP GCOV-utvidelse).
Gcov er et fritt distribuert verktøy for å undersøke kodedekning. Gcov genererer det nøyaktige antallet henrettelser for hver setning i et program og lar deg legge til merknader til kildekoden. Gcov kommer som et standardverktøy som en del av GCC-pakken.
Lcov - grafisk grensesnitt for gcov. Den setter sammen gcov-filer for flere kildefiler og produserer et sett med HTML-sider med kode og dekningsinformasjon. Det genereres også sider for å gjøre navigeringen enklere. Lcov støtter dekning av strenger, funksjoner og grener.
Etter at testene er fullført, vil dekningsinformasjonen bli plassert i coverage/lcov.info.
Vi må si Sonar'Hvor kan jeg få det fra? La oss derfor legge til følgende linjer i konfigurasjonsfilen. Men det er ett poeng: prosjekter kan være flerspråklige, det vil si i mappen src det er kildekoder for flere programmeringsspråk og tilknytning til ett eller annet, og i sin tur bestemmes bruken av en eller annen plugin av utvidelsen. Og dekningsinformasjon kan lagres på forskjellige steder for forskjellige programmeringsspråk, så hvert språk har sin egen seksjon for å sette opp dette. Vårt prosjekt bruker Loggfila, så vi trenger en innstillingsdel bare for det:
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info
Alt er klart for første lansering av skanneren. Jeg vil bemerke at prosjektet er Sonar'e opprettes automatisk første gang du kjører skanneren for et gitt prosjekt. I påfølgende tider vil informasjon bli akkumulert for å se dynamikken i endringer i prosjektparametere over tid.
Så la oss bruke kommandoen som ble opprettet tidligere pakke.json:
yarn run sonar
Merk: du kan også bruke parameteren -X for mer detaljert logging.
Hvis skanneren ble lansert for første gang, vil binærfilen til selve skanneren lastes ned først. Etter det starter den og begynner å skanne serveren Sonar'a for installerte plugins, og beregner dermed støttet språk. Ulike andre parametere for driften er også lastet: kvalitetsprofiler, aktive regler, metrikklager, serverregler.
Merk: Vi vil ikke dvele på dem i detalj innenfor rammen av denne artikkelen, men du kan alltid kontakte offisielle kilder.
Deretter starter mappeanalysen src for tilgjengeligheten av kildefiler for alle (hvis en spesifikk en ikke er eksplisitt spesifisert) støttede språk, med påfølgende indeksering.
Deretter kommer diverse andre analyser, som vi ikke fokuserer på i denne artikkelen (for eksempel linting, gjenkjenning av kodeduplisering osv.).
Helt på slutten av skannerens arbeid blir all innsamlet informasjon samlet, arkivert og sendt til serveren.
Etter dette kan vi allerede se hva som skjedde i nettgrensesnittet:
Som vi kan se, fungerte noe, og viser til og med en slags dekning, men det samsvarer ikke med vår det er-rapportere.
La oss finne ut av det. La oss se på prosjektet mer detaljert, klikk på dekningsverdien og "falle gjennom" i en detaljert filrapport:
Her ser vi, i tillegg til hovedmappe, undersøkt HelloWorld.vue, det er også en fil main.ts, som ødelegger hele bildet av dekningen. Men hvorfor har vi ekskludert det fra dekningsberegningen. Ja, alt er riktig, men det var på nivået det er, men skanneren indekserte det, så det havnet i beregningene.
La oss fikse dette:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...
Jeg vil gjerne gjøre en presisering: i tillegg til mappene som er spesifisert i denne parameteren, legges også alle mappene oppført i parameteren til sonar.test.inkluderinger.
Etter å ha startet skanneren, ser vi riktig informasjon:
La oss se på neste punkt - Kvalitetsprofiler. Jeg snakket ovenfor om støtte Sonarpå flere språk samtidig. Det er akkurat dette vi ser. Men vi vet at prosjektet vårt er skrevet inn TS, så hvorfor anstrenge skanneren med unødvendige manipulasjoner og kontroller. Vi vil angi språket for analyse ved å legge til en parameter til i konfigurasjonsfilen Sonar'EN:
sonar-project.properties:
...
sonar.language=ts
...
La oss kjøre skanneren igjen og se resultatet:
Dekningen var helt borte.
Hvis vi ser på skannerloggen, kan vi se følgende linje:
Det vil si at prosjektfilene våre rett og slett ikke ble indeksert.
Situasjonen er som følger: offisielt støttet VueJs er i plugin-en SonarJShvem er ansvarlig for Javascript.
Men denne støtten er ikke i plugin SonarTS for TS, som en offisiell billett ble åpnet om i feilsporingen Sonar'EN:
Her er noen svar fra en av representantene fra SonarQube-utviklerne, som bekrefter dette faktum.
Men alt fungerte for oss, innvender du. Ja det er det, la oss prøve det litt "hack".
Hvis det er støtte .vue-filer Sonar«å, la oss prøve å fortelle ham om å betrakte dem som Loggfila.
La oss legge til en parameter:
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...
La oss starte skanneren:
Og vips, alt er tilbake til det normale, og med kun én profil for Loggfila. Det vil si at vi klarte å løse problemet i støtte VueJs+TS for soundQube.
La oss prøve å gå videre og forbedre dekningsinformasjonen litt.
Hva vi har gjort så langt:
- lagt til prosjektet Sonar-skanner;
- sette opp det er å generere dekningsinformasjon;
- konfigurert Sonar-skanner;
- løste supportproblemet .vue-filer + Loggfila.
I tillegg til testdekning er det andre interessante nyttige kriterier for kodekvalitet, for eksempel kodeduplisering og antall linjer (involvert i beregning av koeffisienter knyttet til kodekompleksitet) i prosjektet.
I den nåværende implementeringen av plugin for å jobbe med TS (SonarTS) vil ikke fungere CPD (Copy Paste Detector) og telle linjer med kode .vue-filer.
For å lage en syntetisk situasjon med kodeduplisering, duplisere ganske enkelt komponentfilen med et annet navn og også legge den til koden main.ts en dummy-funksjon og duplisere den med et annet navn. For å se etter duplisering som i .vue, og i .ts -filer.
main.ts:
...
function name(params:string): void {
console.log(params);
}
...
For å gjøre dette må du midlertidig kommentere konfigurasjonslinjen:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...
La oss starte skanneren på nytt sammen med testing:
yarn test && yarn run sonar
Selvfølgelig vil dekningen vår falle, men nå er vi ikke interessert i det.
Når det gjelder duplisering av kodelinjer, vil vi se:
For å sjekke vil vi bruke CPD-nytte - jscpd:
npx jscpd src
For kodelinjer:
Kanskje vil dette løses i fremtidige plugin-versjoner SonarJS(TS). Jeg vil merke meg at de gradvis begynner å slå sammen disse to pluginene til ett SonarJS, noe jeg mener er riktig.
Nå ønsket jeg å vurdere muligheten for å forbedre dekningsinformasjonen.
Så langt kan vi se testdekning i prosent for hele prosjektet, og spesielt for filer. Men det er mulig å utvide denne indikatoren med informasjon om mengden enhet-tester for prosjektet, så vel som i sammenheng med filer.
Det er et bibliotek som kan det er-konvertere rapporten til format for Sonar'EN:
generiske testdata -
La oss installere dette biblioteket i prosjektet vårt:
yarn add jest-sonar-reporter
Og legg den til i konfigurasjonen det er:
package.json:
…
"testResultsProcessor": "jest-sonar-reporter"
…
La oss nå kjøre testen:
yarn test
Deretter opprettes en fil i roten av prosjektet test-rapport.xml.
La oss bruke det i konfigurasjonen Sonar'EN:
sonar-project.properties:
…
sonar.testExecutionReportPaths=test-report.xml
…
Og start skanneren på nytt:
yarn run sonar
La oss se hva som har endret seg i grensesnittet Sonar'EN:
Og ingenting har endret seg. Faktum er at Sonar ikke anser filene beskrevet i Jest-rapporten som filer enhet-tester. For å rette opp denne situasjonen bruker vi konfigurasjonsparameteren Sonar sonar.tester, der vi eksplisitt vil indikere mappene med tester (vi har bare en foreløpig):
sonar-project.properties:
…
sonar.tests=src/components/__tests__
…
La oss starte skanneren på nytt:
yarn run sonar
La oss se hva som har endret seg i grensesnittet:
Nå har vi sett tallet på våre enhet-tester og, etter å ha mislyktes ved å klikke på innsiden, kan vi se fordelingen av dette nummeret blant prosjektfilene:
Konklusjon
Så vi så på et verktøy for kontinuerlig analyse soundQube. Vi har vellykket integrert et prosjekt skrevet i den VueJs+TS. Rettet noen kompatibilitetsproblemer. Vi økte informasjonsinnholdet i testdekningsindikatoren. I denne artikkelen undersøkte vi bare ett av kriteriene for kodekvalitet (kanskje et av de viktigste), men soundQube støtter andre kvalitetskriterier, inkludert sikkerhetstesting. Men ikke alle disse funksjonene er fullt tilgjengelige i samfunnet-versjoner. En av de interessante og nyttige funksjonene er integrasjon soundQube med ulike styringssystemer for kodelager, som GitLab og BitBucket. Å forhindre merge pull(merge) request'a til hovedgrenen av depotet når dekningen er forringet. Men dette er en historie for en helt annen artikkel.
PS: Alt beskrevet i artikkelen i form av kode er tilgjengelig i
Kun registrerte brukere kan delta i undersøkelsen.
Bruker du SonarQube-plattformen:
-
26,3%Ja 5
-
15,8%No3
-
15,8%Jeg har hørt om denne plattformen og ønsker å bruke3
-
10,5%Jeg har hørt om denne plattformen og vil ikke bruke2
-
0,0%Jeg bruker en annen plattform0
-
31,6%Første gang jeg har hørt om henne6
19 brukere stemte. 3 brukere avsto.
Kilde: www.habr.com