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, si sono presentati dei problemi. Pertanto, vorrei raccontare in dettaglio come siamo riusciti a risolverli.

Integrazione del progetto VueJS+TS con SonarQube

In questo articolo parleremo, come ho detto sopra, della piattaforma SonarQube. Un po' di teoria: che cos'è esattamente, per chi ne sente parlare per la prima volta:

SonarQube (precedentemente Sonar) è una piattaforma open source per analisi continua e misurazione della qualità del codice.
Supporta l'analisi del codice e la ricerca di errori secondo le regole degli 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 degli errori di programmazione.
Nonostante la piattaforma utilizzi vari strumenti pronti all'uso, SonarQube riunisce i risultati in un unico cruscotto, mantenendo una cronologia delle esecuzioni e permettendo così di vedere la tendenza generale del cambiamento della qualità del software durante lo sviluppo.

Maggiore dettaglio può essere trovato su sito ufficiale

Supporta un gran numero di linguaggi di programmazione. Stando alle informazioni nel link sopra, si tratta di oltre 25 linguaggi. Per supportare un linguaggio specifico è necessario installare il plugin corrispondente. Nella versione community è incluso un plugin per lavorare con Javascript (compreso typescript), anche se nella wiki è scritto il contrario. Per Javascript si occupa del plugin SonarJS, per Typescript SonarTS rispettivamente.

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

Per Javascript c'è npm-wrapper. Quindi, iniziamo l'implementazione passo dopo passo SonarQube in Vue-progetto che utilizza Typescript.

Per il deployment del 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 ciò SonarQube sarà accessibile all'indirizzo – http://localhost:9001 .

Integrazione del progetto VueJS+TS con SonarQube
Attualmente non ci sono progetti e questo è corretto. Risolveremo questa situazione. Ho preso come base il progetto ufficiale di esempio per VueJS+TS+Jest. Lo cloneremo localmente:

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

Prima di tutto, dobbiamo installare il client SonarQube, chiamato sonar-scanner, per npm c'è un wrapper:

yarn add sonarqube-scanner

E aggiungiamo subito il comando in scripts per lavorarci.

package.json:

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

Successivamente, per far funzionare lo scanner, è necessario configurare le impostazioni del progetto in un file speciale. Iniziamo con le basi.

sonar-project.properties:

sonar.host.url=http://localhost:9001

sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Applicazione di Test (VueJS+TS)

sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests*/**
sonar.sourceEncoding=UTF-8

  • sonar.host.url – indirizzo Sonar
  • sonar.projectKey – identificatore univoco del progetto sul server Sonar
  • sonar.projectName – il suo nome, che può essere modificato in qualsiasi momento, poiché l'identificazione del progetto avviene tramite projectKey;
  • sonar.sources – cartella contenente i sorgenti, di solito è src, ma potrebbe essere qualsiasi altra cosa. Questa cartella è definita rispetto alla cartella radice, che è la cartella da cui è stato avviato lo scanner;
  • sonar.tests – parametro che è in coppia con il precedente. È la cartella dove sono presenti i test. In questo progetto, non esiste tale cartella, e il test si trova accanto al componente testato nella cartella ‘test‘, quindi al momento la ignoreremo e utilizzeremo il parametro successivo;
  • sonar.test.inclusions – percorso per i test utilizzando un pattern, possono esserci più elementi elencati tramite virgole;
  • sonar.sourceEncoding – codifica per i file sorgente.

Per la prima esecuzione dello scanner, è tutto pronto, tranne che per l'azione principale preliminare: avviare il motore di test stesso, per generare le informazioni sulla copertura che lo scanner utilizzerà successivamente.

Ma per questo è necessario configurare il motore di test per generare tali 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è, specifichiamo il flag per calcolare la copertura e la fonte (insieme alle eccezioni) su cui essa verrà basata.

Ora eseguiamo il test:

yarn test

Vedremo il seguente:

Integrazione del progetto VueJS+TS con SonarQube

La ragione è che nel componente stesso non c'è codice. Correggiamolo.

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, accertiamoci di questo:

Integrazione del progetto VueJS+TS con SonarQube

Sullo schermo dovremmo vedere informazioni sulla copertura, e nella cartella del progetto verrà creata una cartella copertura con informazioni sulla copertura dei test in un formato universale LCOV (estensione LTP GCOV).

Gcov — un'utilità distribuita liberamente per l'analisi della copertura del codice. Gcov genera il numero preciso di esecuzioni per ogni operatore nel programma e consente di aggiungere annotazioni al codice sorgente. Gcov è fornito come utilità standard all'interno del pacchetto GCC.
Lcov — interfaccia grafica per gcov. Raccoglie i file gcov per diversi file sorgente e crea un insieme di pagine HTML con il codice e informazioni sulla copertura. Vengono generate anche pagine per semplificare la navigazione. Lcov supporta la copertura di righe, funzioni e ramificazioni.

Dopo l'esecuzione dei test, le informazioni sulla copertura saranno presenti in coverage/lcov.info.
Dobbiamo dire Sonardove prenderle. Quindi, aggiungeremo le seguenti righe al suo file di configurazione. Ma c'è un aspetto: i progetti possono essere multilingue, ossia nella cartella src ci sono sorgenti per diversi 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 diversi per diversi linguaggi di programmazione, quindi per ogni linguaggio di programmazione c'è la sua sezione per configurare questo. Il nostro progetto utilizza Typescript, quindi abbiamo bisogno di una sezione di configurazione specifica 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 Sonarviene creato automaticamente alla prima esecuzione dello scanner per questo progetto. Nelle esecuzioni successive, 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: è possibile anche utilizzare il parametro -X per un logging più dettagliato.

Se l'esecuzione dello scanner è stata la prima, prima verrà scaricato il binario dello scanner stesso. Dopo questo, verrà avviato e inizierà a scansionare il server Sonarper i plugin installati, calcolando così i linguaggi di programmazione supportati. Vengono inoltre 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 soffermeremo su di essi in questo articolo, ma è sempre possibile fare riferimento alle fonti ufficiali.

Successivamente, inizia l'analisi della cartella src riguardo alla disponibilità dei file sorgente per tutti (se non è specificato esplicitamente qualche linguaggio di programmazione specifico) supportati, con successiva indicizzazione.

Integrazione del progetto VueJS+TS con SonarQube

Di seguito ci sono altre analisi diverse, su cui non ci soffermiamo in questo articolo (ad esempio, come: linting, rilevazione di codice duplicato, ecc.).

Alla fine del lavoro dello scanner, avviene l'aggregazione di tutte le informazioni raccolte, l'archiviazione e l'invio al server.

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

Integrazione del progetto VueJS+TS con SonarQube

Come possiamo vedere, è emerso qualcosa, e mostra anche una certa copertura, ma non corrisponde al nostro Jest-rapporto.

Diamo uno sguardo più da vicino. Esaminiamo il progetto con maggiore attenzione, clicchiamo sul valore di copertura e "entriamo" nel rapporto dettagliato per file:

Integrazione del progetto VueJS+TS con SonarQube

Qui vediamo, oltre al file principale esaminato HelloWorld.vue, è presente anche il file main.ts, che rovine l'intera immagine della copertura. Ma come mai, l'abbiamo escluso dal calcolo della copertura. Sì, esatto, ma ciò è avvenuto a livello 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 l'avvio dello scanner vediamo già informazioni corrette:

Integrazione del progetto VueJS+TS con SonarQube

Integrazione del progetto VueJS+TS con SonarQube

Analizziamo il prossimo punto – Profili di qualità. Ho detto sopra che supporta Sonardiversi linguaggi di programmazione contemporaneamente. Questo è proprio quello che osserviamo. Ma sappiamo che il nostro progetto è scritto in TS, quindi perché sovraccaricare lo scanner con manovre e controlli inutili. Definiamo 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 è completamente scomparsa.

Se guardiamo nel log dello scanner, possiamo vedere la seguente riga:

Integrazione del progetto VueJS+TS con SonarQube

Cioè, i file del nostro progetto non sono stati semplicemente indicizzati.

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

Integrazione del progetto VueJS+TS con SonarQube

Ma questo supporto non è presente 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 degli sviluppatori di SonarQube, che conferma questo fatto.

Integrazione del progetto VueJS+TS con SonarQube

Integrazione del progetto VueJS+TS con SonarQube

Ma tutto funzionava prima, direte voi. Sì, è vero, proviamo a fare un po' "hackerare".
Se c'è supporto per .vue-file SonarAllora proviamo a dirgli di considerarli come Typescript.

Aggiungiamo un 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 alla normalità, con un profilo solo per Typescript. Quindi siamo riusciti a risolvere il problema del supporto VueJs+TS per SonarQube.

Proviamo a procedere oltre e migliorare un po' le informazioni sulla copertura.

Cosa abbiamo fatto fino ad ora:

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

Oltre alla copertura dei test, ci sono altri criteri interessanti per la qualità del codice, come la duplicazione del codice e il numero di righe (che contribuisce 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 .vue-file.

Per creare una situazione sintetica di duplicazione del codice, duplicheremo semplicemente il file del componente con un nome diverso, aggiungendo anche al codice main.ts una funzione vuota e duplicandola con un nome diverso. Per controllare la duplicazione come in .vue, 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 nostra copertura calerà, ma ora non ci interessa.

Nell'analisi della duplicazione delle righe di codice vedremo:

Integrazione del progetto VueJS+TS con SonarQube

Per il controllo utilizzeremo 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

Probabilmente, questo sarà risolto nelle future versioni dei plugin SonarJS(TS). Vorrei sottolineare che stanno gradualmente unendo questi due plugin in uno SonarJS, il che, penso, sia corretto.

Ora vorrei esaminare un'opzione per migliorare le informazioni sulla copertura.

Finora vediamo la copertura dei test in percentuale, per l'intero progetto e per i file in particolare. Ma c'è la possibilità di ampliare questo indicatore con informazioni sul numero di unit-test nel progetto, così come in dettaglio per file.

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

Instalal questa libreria nel nostro progetto:

yarn add jest-sonar-reporter

E aggiungiamola alla configurazione Jest:

package.json:

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

Ora eseguiamo il test:

yarn test

Dopo di che verrà creato un file test-report.xml.

Utilizziamolo nella configurazione Sonar:

sonar-project.properties:

…
sonar.testExecutionReportPaths=test-report.xml
…

E riavviamo lo scanner:

yarn run sonar

Vediamo cosa è cambiato nell'interfaccia Sonar:

Integrazione del progetto VueJS+TS con SonarQube

E non è cambiato nulla. Il fatto è che Sonar non considera i file descritti nel rapporto Jest come file unit-test. Per risolvere questa situazione utilizziamo un parametro di configurazione Sonar sonar.tests, in cui indicheremo esplicitamente le cartelle con i test (ne abbiamo al momento solo una):

sonar-project.properties:

…
sonar.tests=src/components/__tests__
…

Riavviamo lo scanner:

yarn run sonar

Vediamo cosa è cambiato nell'interfaccia:

Integrazione del progetto VueJS+TS con SonarQube

Ora abbiamo visto il numero dei nostri unit-test e, cliccando all'interno, possiamo vedere la distribuzione di questo numero nei 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 in un progetto scritto in VueJs+TS. Abbiamo risolto alcuni problemi di compatibilità. Abbiamo aumentato la chiarezza del parametro di copertura dei test. In questo articolo abbiamo considerato solo uno dei criteri di qualità del codice (forse uno dei principali), ma SonarQube supporta anche altri criteri di qualità, incluso il testing per la sicurezza. Ma non tutte queste funzionalità sono completamente disponibili nella versione community.Una delle funzionalità interessanti e utili è l'integrazione SonarQube con vari sistemi di gestione dei repository di codice, come GitLab e BitBucket. Per prevenire merge pull(merge) requestnella branch principale del repository in caso di degrado della copertura. Ma questa è già una storia di un altro articolo.

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.

Utilizzate 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%Uso un'altra piattaforma0

  • 31,6%Non ne ho mai sentito parlare6

Hanno votato 19 utenti. Si sono astenuti 3 utenti.

Fonte: habr.com

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