I vores arbejde bruger vi aktivt platformen SonarQube til at opretholde en høj kvalitet af koden. Under integrationen af et projekt skrevet i VueJs+Typescript, opstod der problemer. Derfor vil jeg gerne fortælle nærmere om, hvordan vi løste dem.

Denne artikel vil, som nævnt før, handle om platformen SonarQube. Lidt teori – hvad er det egentlig for en størrelse, for dem der hører om den for første gang:
SonarQube -scale-var Sonar) – er en open source platform til kontinuerlig analyse (eng. continuous inspection) og måling af kodekvalitet.
Den understøtter kodeanalyse og fejlfinding i overensstemmelse med reglerne for programmeringsstandarderne MISRA C, MISRA C++, MITRE/CWE og CERT Secure Coding Standards. Den kan også genkende fejl fra OWASP Top-10 og CWE/SANS Top-25 liste over programmeringsfejl.
Selvom platformen bruger forskellige færdige værktøjer, samler SonarQube resultaterne i et samlet dashboard, der holder styr på historikken af kørselene og dermed giver et overblik over den samlede tendens i ændringen af softwarekvaliteten under udviklingen.
Du kan få mere detaljeret information på
Det understøtter et stort antal programmeringssprog. Ifølge informationen fra linket ovenfor er det mere end 25 sprog. For at understøtte et specifikt sprog skal den relevante plugin installeres. I community-versionen indgår plugin til arbejde med Javascript (herunder typescript), selvom det i wikien er nævnt det modsatte. For Javascript ansvarlig plugin SonarJS, for Typescript SonarTS henholdsvis.
For at sende oplysninger om dækningen bruges den officielle klient sonarqube-scanner, som ved hjælp af indstillingerne fra config-filen sender disse data til serveren SonarQube for yderligere konsolidering og aggregasjon.
For Javascript er . Så lad os begynde med trin-for-trin implementeringen SonarQube i Vue-projektet, der bruger Typescript.
Til at deploye serveren SonarQube vil vi bruge docker-compose.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridgeAktivering:
docker-compose -f sonar.yml upEfter dette SonarQube vil være tilgængelig på adressen – .

Indtil videre er der ingen projekter i den, og det er berettiget. Vi skal rette op på denne situation. Jeg har taget det officielle eksempelprojekt for VueJS+TS+Jest. Vi kloner det til os selv:
git clone https://github.com/vuejs/vue-test-utils-typescript-example.gitFørst skal vi installere klienten SonarQube, som hedder sonar-scanner, for npm der er en wrapper:
yarn add sonarqube-scannerOg lad os straks tilføje kommandoen i scripts for at arbejde med den.
package.json:
{
…
scripts: {
...
"sonar": "sonar-scanner"
...
},
…
}For the scanner to work, you need to set the project settings in a special file. Let's start with the basics.
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 – address Sonar’s;
- sonar.projectKey – unique project identifier on the server Sonar’s;
- sonar.projectName – its name, which can be changed at any time, as project identification is done by projectKey;
- sonar.sources – folder with source files, usually it is src, but it can be anything. This folder is specified relative to the root folder from which the scanner is started;
- sonar.tests – parameter that goes in tandem with the previous one. This is the folder where the tests are located. In this project, there is no such folder, and the test is located next to the component being tested in the folder ‘test‘, so we will ignore it for now and use the next parameter;
- sonar.test.inclusions – path for tests using a mask, multiple items can be listed separated by a comma;
- sonar.sourceEncoding – encoding for source files.
For the first run of the scanner, everything is ready, except for the main prerequisite: running the test engine itself to generate the coverage information that the scanner will use later.
But for this, you need to configure the test engine to generate this information. In this project, the test engine is Jest. And its settings are in the corresponding section of the file package.json.
Let's add these settings:
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*d.*",
"!src/**/*__tests__*"
],That is, we set the flag for the need to calculate coverage and the source (along with the exceptions) based on which it will be formed.
Now let's run the test:
yarn testWe will see the following:

The reason is that there is no actual code in the component. Let's fix this.
HelloWorld.vue:
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...This will be enough for coverage calculation.
After restarting the test, let's confirm this:

On the screen, we should see coverage information, and a folder will be created in the project with coverage coverage information in a universal format LCOV (LTP GCOV extension).
Gcov — gratis tilgængeligt værktøj til at undersøge kode dækning. Gcov genererer det præcise antal kørsel for hver operator i programmet og tillader at tilføje annotationer til kildekoden. Gcov leveres som et standard værktøj i pakkesystemet GCC.
Lcov — grafisk interface til gcov. Det samler gcov-filer for flere kilder og opretter et sæt HTML-sider med koden og dækningsoplysninger. Der genereres også sider for lettere navigation. Lcov understøtter dækning af linjer, funktioner og forgreninger.
Efter testene vil dækning oplysningerne befinde sig i coverage/lcov.info.
Vi skal fortælle Sonarhvornår den skal hentes. Derfor tilføjer vi følgende linjer til dens konfigurationsfil. Men der er et punkt: projekter kan være flersprogede, hvilket betyder, at der i mappen src ligger kildekoder for flere programmeringssprog, og tilknytningen til det eller det andet, og i sin tur bestemmes brugen af det respektive plugin af dets filudvidelse. Informationsdækningen kan derfor opbevares på forskellige steder for forskellige programmeringssprog, således at hvert programmeringssprog har sit eget afsnit til konfiguration. Vores projekt bruger Typescript, derfor har vi brug for et konfigurationsafsnit specifikt til det:
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.infoAlt er klart til den første kørsel af scanneren. Jeg vil bemærke, at projektet i Sonaroprettes automatisk ved den første kørsel af scanneren for dette projekt. Ved efterfølgende kørsel vil oplysningerne allerede blive akkumuleret, så man kan se dynamikken i ændringerne i projektparametre over tid.
Så lad os bruge kommandoen, som vi tidligere har oprettet i package.json:
yarn run sonar Bemærk: man kan også bruge parameteren -X til mere detaljeret logning.
Hvis scanneren køres for første gang, vil binæren af selve scanneren blive downloaded først. Derefter startes den og begynder at scanne serveren Sonarfor installerede plugins, hvilket beregner de understøttede programmeringssprog. Desuden indlæses forskellige andre parametre for dens drift: quality profiles, active rules, metrics repository, server rules.


Bemærk: vi vil ikke gå i dybden med dem i denne artikel, men man kan altid henvise til de officielle kilder.
Dernæst begynder analysen af mappen src vedrørende tilgængeligheden af kildefiler for alle (medmindre en specifik programmeringssprog er angivet) understøttede programmeringssprog, med efterfølgende indeksering.

Der følger forskellige andre analyser, som vi ikke fokuserer på i denne artikel (for eksempel: linting, identifikation af kode-duplication osv.).
I slutningen af scanningsprocessen sker der en aggregering af al den indsamlede information, komprimering og sending til serveren.
Derefter kan vi se, hvad der blev resultatet i webgrænsefladen:

Som vi ser, er der noget kommet ud af det, og det viser endda en vis dækning, men den svarer ikke til vores Jest-rapport.
Lad os finde ud af det. Lad os se nærmere på projektet, klikke på dækningens værdi og "dykke" ind i den detaljerede rapport om filerne:

Her ser vi, udover den primære, undersøgte fil HelloWorld.vue, er der også filen main.ts, som ødelægger hele dækningsbilledet. Men hvordan kunne det være, vi ekskluderede den fra dækningsberegningen. Ja, det er korrekt, men det var på niveauet Jest, men scanneren indekserede den, så den kom med i beregningerne.
Lad os rette dette:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...Det skal nævnes: udover de mapper, der er angivet i denne parameter, tilføjes også alle mapper, der er opført i parameteren sonar.test.inclusions.
Efter scan-processens start ser vi allerede korrekt information:


Lad os diskutere det næste punkt – Quality profiles. Jeg nævnte tidligere, at understøttelse af Sonarflere programmeringssprog samtidig. Det er netop det, vi observerer. Men vi ved, at vores projekt er skrevet i TS, så hvorfor skulle vi belaste scanneren med unødvendige manipulationer og tjek. Sprog til analyse angiver vi ved at tilføje endnu en parameter i konfigurationsfilen Sonarsom:
sonar-project.properties:
...
sonar.language=ts
...Lad os igen køre scanneren og se resultatet:

Dækningen er helt forsvundet.
Hvis vi ser i scannernes log, kan vi finde følgende linje:
![]()
Det vil sige, at vores projekts filer simpelthen ikke blev indekseret.
Situation er følgende: den officielle understøttelse af VueJs findes i pluginet, SonarJSsom håndterer Javascript.

Men denne støtte er ikke tilgængelig i pluginet, SonarTS for TS, hvilket der er oprettet en officiel ticket i bug-tracker. Sonarsom:
Her er nogle svar fra en af repræsentanterne fra SonarQube-udviklerne, der bekræfter dette faktum.


Men det virkede jo alt sammen, vil De indvende. Ja, det gjorde det, lad os prøve at ‘hacke’ det lidt. ‘hacked’.
Hvis der er støtte for .vue-filer. SonarSå lad os prøve at sige til ham, at han skal betragte dem som Typescript.
Lad os tilføje en parameter:
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...Lad os starte scanneren:

Og voilà, alt er blevet som før, og med kun én profil til Typescript. Det vil sige, at vi har løst problemet med understøttelsen VueJs+TS for SonarQube.
Lad os tage et skridt videre og forbedre informationen om dækningen en smule.
Hvad har vi opnået indtil videre:
- tilføjet til projektet Sonar-scanneren;
- konfigureret Jest til at generere information om dækning;
- konfigureret Sonar-scanneren;
- løste understøttelsesproblemet for .vue-filer + Typescript.
Udover testdækningen er der andre interessante kvalitetskriterier for koden, såsom kode duplikering og antal linjer (deltager i beregningen af faktorer relateret til kodekompleksitet) i projektet.
I den nuværende implementering af plugin'et til arbejde med TS (SonarTS) vil ikke fungere CPD (Copy Paste Detector) og tælling af kode linjer .vue-filer.
For at skabe en syntetisk situation for kode duplikering, vil vi blot duplikere komponentfilen med et andet navn, samt tilføje i koden main.ts en dummy-funktion og duplikere den med et andet navn. For at teste duplikering som i .vue. Vi kan gøre dette, da vi har ledige porte (eller vi frigør dem på forhånd) i switchene .ts -filer.
main.ts:
...
function name(params:string): void {
console.log(params);
}
...For dette er det nødvendigt midlertidigt at kommentere konfigurationslinjen:
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...Lad os genstarte scanneren sammen med testningen:
yarn test && yarn run sonarVores dækning vil selvfølgelig falde, men det er ikke vores fokus lige nu.
I forhold til duplikering af kode linjer vil vi se:

Til testen vil vi bruge CPD-værktøjet – jscpd:
npx jscpd src
For kode linjer:

Måske vil dette blive løst i fremtidige versioner af plugin'erne SonarJS(TS). Jeg vil bemærke, at de gradvist begynder at fusionere disse to plugins til ét, SonarJShvilket jeg synes er korrekt.
Nu vil jeg gerne se på muligheden for at forbedre informationen om dækningen.
Indtil videre ser vi testdækningen i procent i hele projektet, og for filerne i særdeleshed. Men der er mulighed for at udvide denne måling med information om antallet unit-af tests i projektet, samt opdelt efter filer.
Der er et bibliotek, der kan Jest-konvertere rapporten til formatet for Sonarsom:
generic test data — .
Lad os installere dette bibliotek i vores projekt:
yarn add jest-sonar-reporterOg lad os tilføje det i konfigurationen Jest:
package.json:
…
"testResultsProcessor": "jest-sonar-reporter"
…Lad os nu udføre testen:
yarn testHvorefter der i rodmappen af projektet vil blive oprettet en fil test-report.xml.
Vi inddrager det i konfigurationen Sonarsom:
sonar-project.properties:
…
sonar.testExecutionReportPaths=test-report.xml
…Og genstarter scanneren:
yarn run sonarLad os se, hvad der er ændret i grænsefladen Sonarsom:

Og der er ikke ændret noget. Det handler om, at Sonar ikke betragter de filer, der er beskrevet i Jest-rapporten, som filer unit-tester. For at rette op på denne situation aktiverer vi konfigurationsparameteren Sonar sonar.tests, hvor vi klart angiver mapperne med tests (vi har kun en indtil videre):
sonar-project.properties:
…
sonar.tests=src/components/__tests__
…Lad os genstarte scanneren:
yarn run sonarLad os se, hvad der er ændret i grænsefladen:

Nu har vi set antallet af vores unit-tester og ved at klikke indad kan vi se fordelingen af dette tal på projektfilerne:

Konklusion
Så, vi har set på værktøjet til kontinuerlig analyse SonarQube. Vi har succesfuldt integreret det i et projekt skrevet i VueJs+TS. Vi har løst nogle kompatibilitetsproblemer. Vi har øget informationsindholdet i testdækningsindikatoren. I denne artikel har vi kun set på et af kvalitetskriterierne (måske et af de vigtigste), men SonarQube understøtter også andre kvalitetskriterier, herunder sikkerhedstestning. Men ikke alle disse muligheder er fuldt tilgængelige i community-versionen. En af de interessante og nyttige funktioner er integrationer SonarQube med forskellige kode-repositorystyringssystemer, såsom GitLab og BitBucket. For at undgå merge pull(merge) requesti hovedgrenen af repositoriet ved forringelse af dækningen. Men det er en historie for en helt anden artikel.
PS: Alt, hvad der er beskrevet i artiklen i form af kode, er tilgængeligt i .
Kun registrerede brugere kan deltage i undersøgelsen. , please.
Bruger du SonarQube-platformen:
26,3%Ja5
15,8%Nej3
15,8%Jeg har hørt om denne platform og ønsker at bruge den3
10,5%Jeg har hørt om denne platform og ønsker ikke at bruge den2
0,0%Jeg bruger en anden platform0
31,6%Jeg hører om den for første gang6
19 brugere har stemt. 3 brugere har undladt at stemme.
Kilde: habr.com
