VueJS+TS projektintegration med SonarQube

Vi bruger aktivt platformen i vores arbejde SonarQube at opretholde kodekvaliteten på et højt niveau. Ved integration af et af projekterne skrevet i VueJs+Typescript, opstod der problemer. Derfor vil jeg gerne fortælle mere detaljeret, hvordan det lykkedes os at løse dem.

VueJS+TS projektintegration med SonarQube

I denne artikel vil vi tale, som jeg skrev ovenfor, om SonarQube-platformen. En lille teori - hvad det er generelt, for dem der hører om det for første gang:

SonarQube (tidligere Sonar) er en open source-platform til kontinuerlig inspektion og måling af kodekvalitet.
Understøtter kodeanalyse og fejldetektion i henhold til reglerne i programmeringsstandarderne MISRA C, MISRA C++, MITER/CWE og CERT Secure Coding Standards. Den kan også genkende fejl fra OWASP Top 10 og CWE/SANS Top 25 programmeringsfejllister.
På trods af at platformen bruger forskellige færdige værktøjer, reducerer SonarQube resultaterne til et enkelt dashboard, holder en historik over kørsler og giver dig derved mulighed for at se den generelle tendens med ændringer i softwarekvalitet under udvikling.

Flere detaljer kan findes på det officielle site

Et stort antal programmeringssprog er understøttet. At dømme efter oplysningerne fra linket ovenfor er der tale om mere end 25 sprog. For at understøtte et bestemt sprog skal du installere det relevante plugin. Fællesskabsversionen indeholder et plugin til at arbejde med Javascript (inklusive typeskrift), selvom wikien siger det modsatte. Bag Javascript plugin-svar SonarJS, for Typescript SonarTS hhv.

Den officielle klient bruges til at sende dækningsoplysninger sonarqube-scanner, som ved hjælp af indstillingerne fra config-fil, sender disse data til serveren SonarQube til yderligere konsolidering og sammenlægning.

for Javascript Der er npm indpakning. Så lad os begynde trin-for-trin implementering SonarQube в Vue-projekt ved hjælp af maskinskrift.

For at implementere serveren SonarQube lad os drage fordel havnearbeider-skriveikonet.

sonar.yaml:

version: '1'
    services:
        simplesample-sonar:
            image: sonarqube:lts
            ports:
                - 9001:9000
                - 9092:9092
            network_mode: bridge

Lancering:

docker-compose -f sonar.yml up

Derefter SonarQube vil være tilgængelig på: http://localhost:9001 .

VueJS+TS projektintegration med SonarQube
Der er ingen projekter i det endnu, og det er rimeligt. Vi vil rette op på denne situation. Jeg tog det officielle eksempelprojekt til VueJS+TS+Jest. Lad os bøje det mod os selv:

git clone https://github.com/vuejs/vue-test-utils-typescript-example.git

Først skal vi installere klienten SonarQube, som kaldes sonar-scannertil NPM der er en indpakning:

yarn add sonarqube-scanner

Og tilføj straks kommandoen til scripts at arbejde med det.

package.json:

{
 … 
   scripts: {
      ...
      "sonar": "sonar-scanner"
      ...
   },
 …
}

Dernæst, for at scanneren skal fungere, skal du indstille projektindstillingerne i en speciel fil. Lad os starte med det grundlæggende.

sonar-projekt.egenskaber:

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.projectNøgle – unik projekt-id på serveren Sonar'EN;
  • sonar.projektnavn – dets navn, det kan ændres til enhver tid, da projektet er identificeret ved projektNøgle;
  • sonar.kilder – mappe med kilder, normalt dette src, men kan være hvad som helst. Denne mappe er sat i forhold til rodmappen, som er den mappe, hvorfra scanneren startes;
  • sonar.tests – en parameter, der går i takt med den foregående. Dette er mappen, hvor testene er placeret. I dette projekt er der ikke en sådan mappe, og testen er placeret ved siden af ​​den komponent, der testes i mappen 'prøve', så vi ignorerer det indtil videre og bruger den næste parameter;
  • sonar.test.optagelser – sti til test ved hjælp af en maske, der kan være flere elementer anført adskilt af kommaer;
  • sonar.sourceEncoding – kodning til kildefiler.

Til den første lancering af scanneren er alt klar, bortset fra den primære foregående handling: lancering af selve testmotoren, så den kan generere information om dækningen, som scanneren efterfølgende vil bruge.

Men for at gøre dette skal du konfigurere testmotoren til at generere disse oplysninger. I dette projekt er testmotoren der er. Og dens indstillinger er i den tilsvarende sektion af filen pakke.json.

Lad os tilføje disse indstillinger:

"collectCoverage": true,
"collectCoverageFrom": [
      "src/**/*",
      "!src/main.ts",
      "!src/App.vue",
      "!src/**/*.d.*",
      "!src/**/*__tests__*"
],

Det vil sige, at vi sætter selve flaget for behovet for at beregne dækning og kilden (sammen med undtagelser), som den vil blive dannet på grundlag af.

Lad os nu køre testen:

yarn test

Vi vil se følgende:

VueJS+TS projektintegration med SonarQube

Årsagen er, at der ikke er nogen kode i selve komponenten. Lad os ordne dette.

HelloWorld.vue:

...
methods: {
    calc(n) {
      return n + 1;
    }
  },
mounted() {
  this.msg1 = this.msg + this.calc(1);
},
...

Dette vil være nok til at beregne dækningen.

Efter genstart af testen vil vi sikre os dette:

VueJS+TS projektintegration med SonarQube

På skærmen skulle vi se information om dækningen, og der oprettes en mappe i projektmappen dækning med oplysninger om testdækning i et universelt format LCOV (LTP GCOV-udvidelse).

Gcov er et frit distribueret hjælpeprogram til at undersøge kodedækning. Gcov genererer det nøjagtige antal henrettelser for hver sætning i et program og giver dig mulighed for at tilføje anmærkninger til kildekoden. Gcov kommer som et standardværktøj som en del af GCC-pakken.
Lcov - grafisk grænseflade til gcov. Den samler gcov-filer til flere kildefiler og producerer et sæt HTML-sider med kode og dækningsoplysninger. Sider genereres også for at gøre navigationen nemmere. Lcov understøtter dækning af strenge, funktioner og grene.

Når testene er afsluttet, vil dækningsoplysninger blive placeret i coverage/lcov.info.
Vi er nødt til at sige Sonar'Hvor kan jeg få det fra? Lad os derfor tilføje følgende linjer til dens konfigurationsfil. Men der er en pointe: projekter kan være flersprogede, det vil sige i mappen src der er kildekoder til flere programmeringssprog og tilknytning til et eller andet, og til gengæld er brugen af ​​et eller andet plugin bestemt af dets udvidelse. Og dækningsoplysninger kan gemmes forskellige steder for forskellige programmeringssprog, så hvert sprog har sin egen sektion til opsætning af dette. Vores projekt bruger maskinskrift, så vi har brug for en indstillingssektion kun til det:

sonar-projekt.egenskaber:

sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info

Alt er klar til den første lancering af scanneren. Jeg vil gerne bemærke, at projektet er Sonar'e oprettes automatisk, første gang du kører scanneren for et givet projekt. I efterfølgende tider vil der blive akkumuleret information for at se dynamikken i ændringer i projektparametre over tid.

Så lad os bruge kommandoen oprettet tidligere pakke.json:

yarn run sonar 

Note: du kan også bruge parameteren -X for mere detaljeret logning.

Hvis scanneren blev lanceret for første gang, downloades selve scannerens binære fil først. Derefter starter den og begynder at scanne serveren Sonar'a for installerede plugins, og beregner derved understøttet sprog. Forskellige andre parametre for dens drift er også indlæst: kvalitetsprofiler, aktive regler, metric repository, serverregler.

VueJS+TS projektintegration med SonarQube

VueJS+TS projektintegration med SonarQube

Note: Vi vil ikke dvæle ved dem i detaljer inden for rammerne af denne artikel, men du kan altid kontakte officielle kilder.

Dernæst begynder mappeanalysen src for tilgængeligheden af ​​kildefiler for alle (hvis en specifik en ikke er eksplicit angivet) understøttede sprog, med deres efterfølgende indeksering.

VueJS+TS projektintegration med SonarQube

Dernæst kommer forskellige andre analyser, som vi ikke fokuserer på i denne artikel (f.eks. linting, detektering af kodeduplikering osv.).

I slutningen af ​​scannerens arbejde bliver al indsamlet information samlet, arkiveret og sendt til serveren.

Herefter kan vi allerede se, hvad der skete i webgrænsefladen:

VueJS+TS projektintegration med SonarQube

Som vi kan se, virkede noget og viser endda en form for dækning, men det matcher ikke vores der er-rapport.

Lad os finde ud af det. Lad os se på projektet mere detaljeret, klik på dækningsværdien og "falde igennem" i en detaljeret filrapport:

VueJS+TS projektintegration med SonarQube

Her ser vi, udover den primære, undersøgte fil HelloWorld.vue, der er også en fil main.ts, hvilket spolerer hele billedet af dækningen. Men hvorfor har vi udelukket det fra beregningen af ​​dækningen. Ja, alt er korrekt, men det var på niveauet der er, men scanneren indekserede det, så det endte i sine beregninger.

Lad os rette dette:

sonar-projekt.egenskaber:

...
sonar.exclusions=src/main.ts
...

Jeg vil gerne gøre en præcisering: Ud over de mapper, der er angivet i denne parameter, tilføjes alle mapper, der er anført i parameteren, også sonar.test.optagelser.

Efter at have startet scanneren, ser vi de korrekte oplysninger:

VueJS+TS projektintegration med SonarQube

VueJS+TS projektintegration med SonarQube

Lad os se på det næste punkt - Kvalitetsprofiler. Jeg talte ovenfor om støtte Sonarpå flere sprog på samme tid. Det er præcis, hvad vi ser. Men vi ved, at vores projekt er skrevet ind TS, så hvorfor belaste scanneren med unødvendige manipulationer og kontroller. Vi indstiller sproget til analyse ved at tilføje en parameter mere til konfigurationsfilen Sonar'EN:

sonar-projekt.egenskaber:

...
sonar.language=ts
...

Lad os køre scanneren igen og se resultatet:

VueJS+TS projektintegration med SonarQube

Dækningen var helt væk.

Hvis vi ser på scannerloggen, kan vi se følgende linje:

VueJS+TS projektintegration med SonarQube

Det vil sige, at vores projektfiler simpelthen ikke blev indekseret.

Situationen er som følger: officielt støttet VueJs er i plugin'et SonarJShvem er ansvarlig for Javascript.

VueJS+TS projektintegration med SonarQube

Men denne support er ikke i plugin'et SonarTS for TS, hvorom der blev åbnet en officiel billet i fejlsporingen Sonar'EN:

  1. https://jira.sonarsource.com/browse/MMF-1441
  2. https://github.com/SonarSource/SonarJS/issues/1281

Her er nogle svar fra en af ​​repræsentanterne fra SonarQube-udviklerne, der bekræfter dette faktum.

VueJS+TS projektintegration med SonarQube

VueJS+TS projektintegration med SonarQube

Men alt fungerede for os, indvender du. Ja det er det, lad os prøve det lidt "hack".
Hvis der er støtte .vue-filer Sonar'åh, så lad os prøve at fortælle ham, at han skal betragte dem som maskinskrift.

Lad os tilføje en parameter:

sonar-projekt.egenskaber:

...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...

Lad os starte scanneren:

VueJS+TS projektintegration med SonarQube

Og voila, alt er tilbage til det normale, og kun med én profil for maskinskrift. Det vil sige, at vi formåede at løse problemet i support VueJs+TS for SonarQube.

Lad os prøve at gå videre og forbedre dækningsoplysningerne lidt.

Hvad vi har gjort indtil videre:

  • tilføjet til projektet Sonar-scanner;
  • Opsætning der er at generere dækningsoplysninger;
  • konfigureret Sonar-scanner;
  • løste supportproblemet .vue-filer + maskinskrift.

Ud over testdækning er der andre interessante nyttige kriterier for kodekvalitet, for eksempel kodeduplikering og antallet af linjer (involveret i beregningen af ​​koefficienter relateret til kodekompleksitet) i projektet.

I den nuværende implementering af plugin til at arbejde med TS (SonarTS) vil ikke virke CPD (Copy Paste Detector) og tælle kodelinjer .vue-filer.

For at skabe en syntetisk situation med kodeduplikering skal du blot duplikere komponentfilen med et andet navn og også tilføje den til koden main.ts en dummy-funktion og duplikere den med et andet navn. For at kontrollere for duplikering som i .vue, og i .ts -filer.

main.ts:

...
function name(params:string): void {
  console.log(params);
}
...

For at gøre dette skal du midlertidigt kommentere konfigurationslinjen:

sonar-projekt.egenskaber:

...
sonar.exclusions=src/main.ts
...

Lad os genstarte scanneren sammen med test:

yarn test && yarn run sonar

Selvfølgelig falder vores dækning, men nu er vi ikke interesserede i det.

Med hensyn til duplikering af kodelinjer vil vi se:

VueJS+TS projektintegration med SonarQube

For at kontrollere vil vi bruge CPD-nytte - jscpd:

npx jscpd src

VueJS+TS projektintegration med SonarQube

For kodelinjer:

VueJS+TS projektintegration med SonarQube

Måske vil dette blive løst i fremtidige plugin-versioner SonarJS(TS). Jeg vil gerne bemærke, at de gradvist begynder at fusionere disse to plugins til ét SonarJS, hvilket jeg synes er rigtigt.

Nu ville jeg overveje muligheden for at forbedre dækningsoplysningerne.

Indtil videre kan vi se testdækning i procent, for hele projektet og for filer i særdeleshed. Men det er muligt at udvide denne indikator med oplysninger om mængden enhed-tests for projektet, samt i sammenhæng med filer.

Der er et bibliotek, der kan der er-konvertere rapporten til format for Sonar'EN:
generiske testdatahttps://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

Lad os installere dette bibliotek i vores projekt:

yarn add jest-sonar-reporter

Og føj det til konfigurationen der er:

package.json:

…
"testResultsProcessor": "jest-sonar-reporter"
…

Lad os nu køre testen:

yarn test

Hvorefter der oprettes en fil i projektets rod test-rapport.xml.

Lad os bruge det i konfigurationen Sonar'EN:

sonar-projekt.egenskaber:

…
sonar.testExecutionReportPaths=test-report.xml
…

Og genstart scanneren:

yarn run sonar

Lad os se, hvad der har ændret sig i grænsefladen Sonar'EN:

VueJS+TS projektintegration med SonarQube

Og intet har ændret sig. Faktum er, at Sonar ikke betragter filerne beskrevet i Jest-rapporten som filer enhed-prøver. For at rette op på denne situation bruger vi konfigurationsparameteren Sonar sonar.tests, hvori vi eksplicit vil angive mapperne med tests (vi har kun én i øjeblikket):

sonar-projekt.egenskaber:

…
sonar.tests=src/components/__tests__
…

Lad os genstarte scanneren:

yarn run sonar

Lad os se, hvad der er ændret i grænsefladen:

VueJS+TS projektintegration med SonarQube

Nu har vi set antallet af vores enhed-test, og efter at have fejlet ved at klikke inde, kan vi se fordelingen af ​​dette nummer blandt projektfilerne:

VueJS+TS projektintegration med SonarQube

Konklusion

Så vi så på et værktøj til kontinuerlig analyse SonarQube. Vi har med succes integreret et projekt skrevet i det VueJs+TS. Rettede nogle kompatibilitetsproblemer. Vi øgede informationsindholdet i testdækningsindikatoren. I denne artikel undersøgte vi kun et af kodekvalitetskriterierne (måske et af de vigtigste), men SonarQube understøtter andre kvalitetskriterier, herunder sikkerhedstest. Men ikke alle disse funktioner er fuldt tilgængelige i samfund-versioner. En af de interessante og nyttige funktioner er integration SonarQube med forskellige kodelagerstyringssystemer, såsom GitLab og BitBucket. At forhindre merge pull(merge) anmodning'a til depotets hovedgren, når dækningen er forringet. Men dette er en historie til en helt anden artikel.

PS: Alt beskrevet i artiklen i form af kode er tilgængeligt i min gaffel.

Kun registrerede brugere kan deltage i undersøgelsen. Log ind, Vær venlig.

Bruger du SonarQube platformen:

  • 26,3 %Ja 5

  • 15,8 %Nr 3

  • 15,8 %Jeg har hørt om denne platform og vil gerne bruge3

  • 10,5 %Jeg har hørt om denne platform og ønsker ikke at bruge2

  • 0,0 %Jeg bruger en anden platform0

  • 31,6 %Det er første gang, jeg har hørt om hende6

19 brugere stemte. 3 brugere undlod at stemme.

Kilde: www.habr.com

Tilføj en kommentar