Integrazione del progetto VueJS+TS con SonarQube

Nel nostro lavoro utilizziamo attivamente la piattaforma SonarQube per mantenere alta la qualità del codice. Durante l'integrazione di uno dei progetti, scritto in VueJs+Typescript, abbiamo riscontrato dei problemi. Vorrei quindi raccontare più dettagliatamente come siamo riusciti a risolverli.

Integrazione del progetto VueJS+TS con SonarQube

In questo articolo si parlerà, come ho già accennato, della piattaforma SonarQube. Un po' di teoria - che cos'è in realtà, per chi la sente per la prima volta:

SonarQube (ex Sonar) - una piattaforma open source per l'analisi continua (in inglese continuous inspection) e la misurazione della qualità del codice.
Supporta l'analisi del codice e la ricerca di errori secondo le norme standard di programmazione MISRA C, MISRA C++, MITRE/CWE e CERT Secure Coding Standards. Inoltre, è in grado di riconoscere errori dalle liste OWASP Top-10 e CWE/SANS Top-25 di errori di programmazione.
Nonostante la piattaforma utilizzi diversi strumenti preconfezionati, SonarQube riduce i risultati a un'unica dashboard, mantenendo la cronologia delle esecuzioni e permettendo di vedere la tendenza generale del cambiamento della qualità del software durante lo sviluppo.

È possibile saperne di più su sito ufficiale

Supporta un gran numero di linguaggi di programmazione. A giudicare dalle informazioni nel link sopra - si tratta di oltre 25 linguaggi. Per supportare un linguaggio specifico è necessario installare il relativo plugin. Nella versione community è incluso un plugin per lavorare con Javascript (incluso typescript), anche se nella wiki è scritto il contrario. La Javascript è gestita dal plugin SonarJS, mentre per Typescript SonarTS rispettivamente.

Per inviare informazioni sulla copertura si utilizza il client ufficiale sonarqube-scanner, che, utilizzando le impostazioni da config-file, invia questi dati al server SonarQube per ulteriore consolidamento e aggregazione.

Per Javascript ci siano wrapper npm. Iniziamo quindi l'implementazione passo passo SonarQube in Vue-progetto, che utilizza Typescript.

Per distribuire il server SonarQube utilizzeremo docker-compose.

sonar.yaml:

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

Avvio:

docker-compose -f sonar.yml up

Dopo di che SonarQube sarà accessibile all'indirizzo - http://localhost:9001 .

Integrazione del progetto VueJS+TS con SonarQube
Per ora non ci sono progetti e questo è giustificato. Presto risolveremo questa situazione. Ho preso come base un progetto ufficiale di esempio per VueJS+TS+Jest. Cloniamolo:

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

Per prima cosa dobbiamo installare il client SonarQube, che si chiama sonar-scanner, per npm c'è un wrapper:

yarn add sonarqube-scanner

E subito aggiungiamo un comando in scripts per lavorarci.

package.json:

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

In seguito, per far funzionare lo scanner, è necessario configurare le impostazioni del progetto in un file speciale. Iniziamo con quelle di base.

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 – l'indirizzo Sonardel server;
  • sonar.projectKey – identificatore unico del progetto sul server Sonardel server;
  • sonar.projectName – il suo nome, che può essere modificato in qualsiasi momento, poiché l'identificazione del progetto avviene attraverso projectKey;
  • sonar.sources – cartella contenente il codice sorgente, di solito questa è src, ma può essere qualsiasi altra. Questa cartella è definita rispetto alla cartella di root, che è la cartella da cui viene eseguito lo scanner;
  • sonar.tests – parametro che va in coppia con il precedente. Questa è la cartella dove si trovano i test. In questo progetto, non c'è una cartella del genere, ma il test si trova accanto al componente testato nella cartella ‘test‘, quindi per ora la ignoreremo e utilizzeremo il parametro successivo;
  • sonar.test.inclusions – percorso per i test utilizzando una maschera, possono esserci più elementi elencati separati da virgole;
  • sonar.sourceEncoding – codifica per i file sorgente.

Per il primo avvio dello scanner, è tutto pronto, tranne l'azione principale preliminare: avviare il motore di test stesso, per generare informazioni sulla copertura, che verrà poi utilizzata dallo scanner.

Ma per questo è necessario configurare il motore di test per generare queste informazioni. In questo progetto, il motore di test è Jest. E le sue impostazioni si trovano nella sezione corrispondente del file. package.json.

Aggiungiamo queste impostazioni:

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

Cioè, impostiamo il flag per la necessità di calcolare la copertura e la fonte (insieme alle eccezioni) su cui verrà calcolata.

Ora facciamo partire il test:

yarn test

Dovremmo vedere quanto segue:

Integrazione del progetto VueJS+TS con SonarQube

La ragione è che nel componente stesso non ci sono, di fatto, codici. Sistemiamo questo.

HelloWorld.vue:

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

Questo sarà sufficiente per il calcolo della copertura.

Dopo aver riavviato il test, verifichiamo:

Integrazione del progetto VueJS+TS con SonarQube

Dovremmo vedere informazioni sulla copertura sullo schermo, e nella cartella del progetto verrà creata una cartella coverage con le informazioni sulla copertura dei test in formato universale LCOV (LTP GCOV extension).

Gcov — strumento open source per l'analisi della copertura del codice. Gcov genera il numero esatto di esecuzioni per ogni istruzione nel programma e consente di aggiungere annotazioni al codice sorgente. Gcov è fornito come strumento standard all'interno del pacchetto GCC.
Lcov — interfaccia grafica per gcov. Raccoglie file gcov per più file sorgente e crea un insieme di pagine HTML con il codice e le informazioni sulla copertura. Vengono anche generate pagine per facilitare la navigazione. Lcov supporta la copertura di righe, funzioni e diramazioni.

Dopo aver eseguito i test, le informazioni sulla copertura saranno presenti in coverage/lcov.info.
Dobbiamo dire Sonarda dove prelevarla. Pertanto, aggiungeremo le seguenti righe al suo file di configurazione. Ma c'è un punto: i progetti possono essere multilingue, il che significa che nella cartella src ci sono sorgenti per più linguaggi di programmazione, e l'appartenenza a uno o l'altro, e a sua volta l'uso di un determinato plugin, è determinato dalla sua estensione. E le informazioni sulla copertura possono essere memorizzate in luoghi differenti per diversi linguaggi di programmazione, quindi per ogni linguaggio di programmazione c'è una sezione di configurazione dedicata. Il nostro progetto utilizza Typescript, quindi abbiamo bisogno di una sezione di configurazione specificamente per esso:

sonar-project.properties:

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

Tutto è pronto per la prima esecuzione dello scanner. Voglio notare che il progetto in Sonarè creato automaticamente al primo avvio dello scanner per questo progetto. Alle successive esecuzioni, le informazioni saranno già accumulate per vedere la dinamica delle variazioni dei parametri del progetto nel tempo.

Quindi, utilizziamo il comando creato in precedenza in package.json:

yarn run sonar 

Nota: si può anche utilizzare il parametro -X per una registrazione più dettagliata.

Se lo scanner è stato avviato per la prima volta, verrà prima scaricato il file binario dello scanner stesso. Dopo di che viene avviato e inizia a scansionare il server Sonarper cercare i plugin installati, calcolando così i linguaggi di programmazione supportati. Vengono anche caricati altri vari parametri per il suo funzionamento: quality profiles, active rules, metrics repository, server rules.

Integrazione del progetto VueJS+TS con SonarQube

Integrazione del progetto VueJS+TS con SonarQube

Nota: non ci fermeremo su di essi in questo articolo, ma si può sempre fare riferimento alle fonti ufficiali.

Quindi inizia l'analisi della cartella src per verificare la presenza di file sorgente per tutti (se non è stato specificato esplicitamente alcun particolare) linguaggi di programmazione supportati, con successiva indicizzazione.

Integrazione del progetto VueJS+TS con SonarQube

Quindi ci sono altre varie analisi, su cui non ci soffermiamo in questo articolo (ad esempio, come: linting, determinazione del codice duplicato, ecc.).

Alla fine del lavoro dello scanner, tutte le informazioni raccolte vengono aggregate, archiviate e inviate al server.

Dopo di che possiamo già vedere cosa è venuto fuori nell'interfaccia web:

Integrazione del progetto VueJS+TS con SonarQube

Come vediamo, è venuto fuori qualcosa, e mostra anche una certa copertura, ma non corrisponde al nostro Jest-report.

Cerchiamo di capire. Diamo un'occhiata al progetto più in dettaglio, clicchiamo sul valore della copertura e "entriamo" nel rapporto dettagliato per i file:

Integrazione del progetto VueJS+TS con SonarQube

Qui vediamo, oltre al file principale in esame HelloWorld.vue, c'è anche il file main.ts, che rovina l'intera situazione della copertura. Ma come mai, lo escludevamo dal calcolo della copertura. Sì, è tutto corretto, ma questo era a livello di Jest, ma lo scanner lo ha indicizzato, quindi è entrato nei suoi calcoli.

Correggiamo questo:

sonar-project.properties:

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

Vorrei fare una precisazione: oltre alle cartelle specificate in questo parametro, vengono aggiunte anche tutte le cartelle elencate nel parametro sonar.test.inclusions.

Dopo aver eseguito lo scanner, vediamo già informazioni corrette:

Integrazione del progetto VueJS+TS con SonarQube

Integrazione del progetto VueJS+TS con SonarQube

Esaminiamo il prossimo punto – Quality profiles. Ho detto sopra che il supporto di Sonarconsente di utilizzare più linguaggi di programmazione contemporaneamente. Questo è proprio ciò che stiamo osservando. Ma sappiamo che il nostro progetto è scritto in TS, quindi perché affaticare lo scanner con manovre e controlli inutili. Vogliamo impostare il linguaggio per l'analisi aggiungendo un altro parametro al file di configurazione Sonar:

sonar-project.properties:

...
sonar.language=ts
...

Riavviamo lo scanner e vediamo il risultato:

Integrazione del progetto VueJS+TS con SonarQube

La copertura è scomparsa del tutto.

Se diamo un'occhiata al log dello scanner, possiamo vedere la seguente riga:

Integrazione del progetto VueJS+TS con SonarQube

Vale a dire che i file del nostro progetto semplicemente non sono stati indicizzati.

La situazione è la seguente: ufficialmente il supporto per VueJs è presente nel plugin SonarJS, che si occupa di Javascript.

Integrazione del progetto VueJS+TS con SonarQube

Ma non c'è questo supporto nel plugin SonarTS per TS, di cui è stato aperto un ticket ufficiale nel bug tracker Sonar:

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

Ecco alcune risposte di uno dei rappresentanti da parte degli sviluppatori di SonarQube, che confermando questo fatto.

Integrazione del progetto VueJS+TS con SonarQube

Integrazione del progetto VueJS+TS con SonarQube

Ma tutto funzionava, potreste obiettare. Sì, è così, proviamo a "hackerare" un po'. Se c'è supporto per.
.vue -file, allora proviamo a dirgli di trattarli come SonarAggiungiamo il parametro: Typescript.

Aggiungiamo il parametro:

sonar-project.properties:

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

Avviamo lo scanner:

Integrazione del progetto VueJS+TS con SonarQube

E, voilà, tutto è tornato come prima, con un solo profilo dedicato a Typescript. Quindi, abbiamo risolto il problema di supporto per VueJs+TS per SonarQube.

Proviamo a fare un passo avanti per migliorare ulteriormente le informazioni sulla copertura.

Cosa abbiamo fatto finora:

  • abbiamo aggiunto al progetto Sonar-scanner;
  • configurato Jest per generare informazioni sulla copertura;
  • configurato Sonar-scanner;
  • abbiamo risolto il problema di supporto per -file-file + Typescript.

Oltre alla copertura con i test, esistono altri interessanti criteri di qualità del codice, come la duplicazione del codice e il conteggio delle righe (che partecipano al calcolo dei coefficienti legati alla complessità del codice) del progetto.

Nell'attuale implementazione del plugin per lavorare con TS (SonarTS) non funzionerà CPD (Copy Paste Detector) e il conteggio delle righe di codice -file-file.

Per creare una situazione sintetica di duplicazione del codice, semplicemente duplicheremo il file del componente con un altro nome, e aggiungeremo al codice main.ts una funzione vuota e la copieremo con un altro nome. Per controllare il duplicato come in -file, sia in .ts -file.

main.ts:

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

Per questo, è necessario commentare temporaneamente la riga di configurazione:

sonar-project.properties:

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

Riavviamo lo scanner insieme ai test:

yarn test && yarn run sonar

Certo, la copertura diminuirà, ma al momento non ci interessa.

In termini di duplicazione delle righe di codice, vedremo:

Integrazione del progetto VueJS+TS con SonarQube

Per la verifica utilizziamo CPD-utility – jscpd:

npx jscpd src

Integrazione del progetto VueJS+TS con SonarQube

Per le righe di codice:

Integrazione del progetto VueJS+TS con SonarQube

Potrebbe risolversi nelle versioni future dei plugin SonarJS(TS). Vorrei notare che stanno lentamente fondendo questi due plugin in uno solo SonarJS, il che penso sia corretto.

Ora vorrei considerare un modo per migliorare le informazioni sulla copertura.

Attualmente vediamo la copertura dei test in percentuale, sia per l'intero progetto che per file specifici. Ma abbiamo la possibilità di ampliare questo indicatore con informazioni sul numero un'unità-di test del progetto, così come analizzare i singoli file.

C’è una libreria in grado di Jest-convertire il report per Sonar:
generic test datahttps://docs.sonarqube.org/display/SONAR/Generic+Test+Data.

Installeremo questa libreria nel nostro progetto:

yarn add jest-sonar-reporter

E l’aggiungiamo nella configurazione Jest:

package.json:

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

Ora eseguiamo il test:

yarn test

Dopo di che, nella radice del progetto verrà creato il file test-report.xml.

Lo utilizzeremo nella configurazione Sonar:

sonar-project.properties:

…
sonar.testExecutionReportPaths=test-report.xml
…

E riavviamo lo scanner:

yarn run sonar

Diamo un’occhiata a cosa è cambiato nell’interfaccia Sonar:

Integrazione del progetto VueJS+TS con SonarQube

E nulla è cambiato. Il fatto è che Sonar non considera i file descritti nel report di Jest come file un'unità-test. Per risolvere questa situazione, utilizziamo un parametro di configurazione Sonar sonar.tests, dove specifichiamo chiaramente le cartelle dei test (per ora ne abbiamo solo una):

sonar-project.properties:

…
sonar.tests=src/components/__tests__
…

Riavviamo lo scanner:

yarn run sonar

Diamo un’occhiata a cosa è cambiato nell’interfaccia:

Integrazione del progetto VueJS+TS con SonarQube

Ora abbiamo visto il numero dei nostri un'unità-test e, cliccando, possiamo controllare la distribuzione di questo numero tra i file del progetto:

Integrazione del progetto VueJS+TS con SonarQube

Conclusione

Quindi, abbiamo esaminato uno strumento per l'analisi continua SonarQube. L'abbiamo integrato con successo nel progetto, sviluppato in VueJs+TS. Abbiamo risolto alcuni problemi di compatibilità. Abbiamo aumentato la rilevanza dell'indicatore di copertura dei test. In questo articolo abbiamo trattato solo uno dei criteri di qualità del codice (probabilmente uno dei più importanti), ma SonarQube supporta anche altri criteri di qualità, incluso il testing della sicurezza. Tuttavia, non tutte queste funzionalità sono completamente disponibili nella community-versione. Una delle interessanti e utili funzionalità è l'integrazione SonarQube con diversi sistemi di gestione dei repository di codice, come GitLab e BitBucket. Per evitare merge pull(merge) requestnella branch principale del repository in caso di degradazione della copertura. Ma questa è già un'altra storia.

PS: Tutto ciò che è descritto nell'articolo in forma di codice è disponibile nel mio fork.

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

Usi la piattaforma SonarQube:

  • 26,3%Sì5

  • 15,8%No3

  • 15,8%Ho sentito parlare di questa piattaforma e voglio usarla3

  • 10,5%Ho sentito parlare di questa piattaforma e non voglio usarla2

  • 0,0%Utilizzo un'altra piattaforma0

  • 31,6%Ne sento parlare per la prima volta6

Hanno votato 19 utenti. Si sono astenuti 3 utenti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster