Dans notre travail, nous utilisons activement la plateforme SonarQube pour maintenir la qualité du code à un niveau élevé. Lors de l'intégration d'un des projets, écrit en VueJs+Typescript, des problèmes sont survenus. C'est pourquoi je voudrais expliquer en détail comment nous avons réussi à les résoudre.

Cet article portera, comme je l'ai mentionné précédemment, sur la plateforme SonarQube. Un peu de théorie - qu'est-ce que c'est, pour ceux qui en entendent parler pour la première fois :
SonarQube -scale-var Sonar) est une plateforme open source pour l'analyse continue (en anglais : continuous inspection) et la mesure de la qualité du code.
Elle prend en charge l'analyse du code et la recherche d'erreurs selon les règles des normes de programmation MISRA C, MISRA C++, MITRE/CWE et CERT Secure Coding Standards. Elle peut également reconnaître les erreurs des listes OWASP Top 10 et CWE/SANS Top 25 erreurs de programmation.
Bien que la plateforme utilise divers outils prêts à l'emploi, SonarQube consolide les résultats sur un tableau de bord unique (en anglais : dashboard), tenant un historique des exécutions et permettant ainsi de voir la tendance générale de l'évolution de la qualité du logiciel tout au long du développement.
Pour en savoir plus, vous pouvez consulter le
Un grand nombre de langages de programmation sont pris en charge. D'après l'information du lien ci-dessus, cela concerne plus de 25 langages. Pour prendre en charge un langage spécifique, il est nécessaire d'installer le plugin correspondant. La version community inclut un plugin pour travailler avec Javascript (y compris typescript), bien que la wiki indique le contraire. Pour Javascript cela, le plugin SonarJS, pour TypeScript SonarTS respectivement.
Pour envoyer des informations sur la couverture, on utilise le client officiel sonarqube-scanner, qui, en utilisant les paramètres du fichier config-envoie ces données au serveur SonarQube pour une consolidation et une agrégation ultérieures.
Pour Javascript Il existe . Alors, commençons l'implémentation étape par étape d'un SonarQube dans projet Vue-utilisant TypeScript.
Pour déployer le serveur SonarQube nous utiliserons docker-compose.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridgeLancement :
docker-compose -f sonar.yml upAprès cela, SonarQube il sera accessible à l'adresse – .

Pour l'instant, il n'y a pas de projets et c'est vrai. Nous allons rectifier cette situation. J'ai pris comme base le projet d'exemple officiel pour VueJS+TS+Jest. Nous allons le cloner :
git clone https://github.com/vuejs/vue-test-utils-typescript-example.gitTout d'abord, nous devons installer le client SonarQube, qui s'appelle sonar-scanner, pour npm il existe un wrapper:
yarn add sonarqube-scannerEt ajoutons tout de suite la commande dans scripts pour travailler avec.
package.json :
{
…
scripts: {
...
"sonar": "sonar-scanner"
...
},
…
}Ensuite, pour faire fonctionner le scanner, il faut définir les paramètres du projet dans un fichier spécial. Commençons par les basiques.
sonar-project.properties:
sonar.host.url=http://localhost:9001
sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Application Test (VueJS+TS)
sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests**
sonar.sourceEncoding=UTF-8- sonar.host.url – adresse Sonar’a;
- sonar.projectKey – identifiant unique du projet sur le serveur Sonar’a;
- sonar.projectName – son nom, il peut être modifié à tout moment, car l'identification du projet se fait par projectKey;
- sonar.sources – dossier contenant les sources, généralement c'est src, mais cela peut être n'importe quoi. Ce dossier est défini par rapport au dossier racine, qui est le dossier depuis lequel le scanner est lancé;
- sonar.tests – paramètre qui va de pair avec le précédent. C'est le dossier où se trouvent les tests. Dans ce projet, il n'y a pas tel dossier, et le test se trouve à côté du composant testé dans le dossier 'test', c'est pourquoi nous allons l'ignorer pour l'instant et utiliser le paramètre suivant;
- sonar.test.inclusions – chemin pour les tests utilisant un masque, il peut y avoir plusieurs éléments énumérés par une virgule;
- sonar.sourceEncoding – encodage pour les fichiers sources.
Pour le premier lancement du scanner, tout est prêt, sauf l'action préalable principale : lancer le moteur de test lui-même, afin de lui faire générer les informations sur la couverture, que le scanner utilisera par la suite.
Mais pour cela, il faut configurer le moteur de test pour générer cette information. Dans ce projet, le moteur de test est Jest. Et ses paramètres se trouvent dans la section correspondante du fichier package.json.
Ajoutons ces paramètres :
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*.d.*",
"!src/**/*__tests__*"
],C'est-à-dire que nous définissons le drapeau nécessaire au calcul de la couverture et la source (avec les exceptions), sur la base desquelles elle sera calculée.
Maintenant, lançons le test :
yarn testNous devrions voir le suivant :

La raison est que dans le composant lui-même, il n'y a pas vraiment de code. Corrigeons cela.
HelloWorld.vue :
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...Cela devrait suffire pour le calcul de la couverture.
Après avoir redémarré le test, vérifions cela :

À l'écran, nous devrions voir les informations sur la couverture, et dans le dossier du projet, un dossier sera créé. couverture informations sur la couverture des tests dans un format universel LCOV (extension de LTP GCOV).
Gcov — un utilitaire open source pour l'analyse de la couverture du code. Gcov génère le nombre exact d'exécutions pour chaque instruction dans le programme et permet d'ajouter des annotations au code source. Gcov est fourni en tant qu'utilitaire standard dans le package GCC.
Lcov — une interface graphique pour gcov. Il collecte des fichiers gcov pour plusieurs fichiers sources et crée un ensemble de pages HTML avec le code et des informations sur la couverture. Des pages sont également générées pour faciliter la navigation. Lcov prend en charge la couverture des lignes, des fonctions et des branches.
Après l'exécution des tests, les informations sur la couverture se trouveront dans coverage/lcov.info.
Nous devons indiquer Sonard'où les obtenir. Nous allons donc ajouter les lignes suivantes à son fichier de configuration. Mais il y a un point à noter : les projets peuvent être multilingues, c'est-à-dire que dans le dossier src se trouvent les sources pour plusieurs langages de programmation et l'appartenance à l'un ou l'autre, et l'utilisation d'un plugin en particulier, est déterminée par son extension. Les informations sur la couverture peuvent être stockées à différents endroits pour différents langages de programmation, c'est pourquoi chaque langage de programmation a sa propre section de configuration. Notre projet utilise TypeScript, nous avons donc besoin d'une section de configuration spécifiquement pour lui :
sonar-project.properties:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.infoTout est prêt pour le premier lancement du scanner. Je tiens à souligner qu'un projet dans Sonarest créé automatiquement lors du premier lancement du scanner pour ce projet. Lors des lancements suivants, les informations seront accumulées pour voir la dynamique des changements de paramètres du projet au fil du temps.
Alors, utilisons la commande créée précédemment dans package.json:
yarn run sonar Remarque : vous pouvez également utiliser le paramètre -X pour un journal détaillé.
Si le scanner a été lancé pour la première fois, le binaire du scanner lui-même sera d'abord téléchargé. Ensuite, il est lancé et commence à scanner le serveur Sonarà la recherche de plugins installés, calculant ainsi les langages de programmation pris en charge. D'autres paramètres divers pour son fonctionnement sont également chargés : quality profiles, active rules, metrics repository, server rules.


Remarque : nous ne nous attarderons pas sur eux dans le cadre de cet article, mais on peut toujours se référer aux sources officielles.
Ensuite, l'analyse du dossier commence src concernant la disponibilité des fichiers sources pour tous les langages de programmation pris en charge (s'il n'y a pas de spécification explicite d'un langage particulier), suivie de leur indexation.

Ensuite, il y a d'autres analyses variées sur lesquelles nous ne nous attardons pas dans cet article (comme : le linting, la détection de duplications de code, etc.).
À la fin du travail du scanner, toutes les informations collectées sont agrégées, archivées et envoyées au serveur.
Après cela, nous pouvons déjà voir ce que nous avons obtenu dans l'interface web :

Comme nous le voyons, quelque chose a été produit, et cela montre même une certaine couverture, mais elle ne correspond pas à notre Jest-rapport.
Essayons de comprendre. Regardons le projet plus en détail, cliquons sur la valeur de couverture, et "plongeons" dans le rapport détaillé par fichiers :

Ici, nous voyons en plus du fichier principal étudié HelloWorld.vue, il y a aussi le fichier main.ts, qui fausse toute l'image de la couverture. Mais comment cela se fait-il, nous l'avons exclu du calcul de la couverture. Oui, c'est exact, mais c'était au niveau Jest, mais le scanner l'a indexé, donc il fait partie de ses calculs.
Corrigeons cela :
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...Je tiens à préciser : en plus des dossiers spécifiés dans ce paramètre, tous les dossiers répertoriés dans le paramètre sonar.test.inclusions.
Après avoir lancé le scanner, nous voyons déjà des informations correctes :


Examinons le point suivant – Profils de qualité. J'ai mentionné plus haut que le support de plusieurs langages de programmation simultanément est possible. C'est exactement ce que nous observons. Mais nous savons que notre projet est écrit en SonarTS , donc pourquoi solliciter inutilement le scanner avec des manipulations et des vérifications supplémentaires. Nous définirons le langage d'analyse en ajoutant un autre paramètre dans le fichier de configuration: Sonar... sonar.language=ts ...
sonar-project.properties:
Relançons le scanner et voyons le résultat :La couverture a complètement disparu.

Si nous regardons dans le journal du scanner, nous pouvons voir la ligne suivante :
C'est-à-dire que les fichiers de notre projet n'ont tout simplement pas été indexés.
![]()
La situation est la suivante : la prise en charge officielle de
VueJs est présente dans le plugin , qui s'occupe de SonarJS. Mais cette prise en charge n'est pas présente dans le plugin Javascript.

, comme le confirme un ticket dans le suivi des bugs. SonarTS pour , donc pourquoi solliciter inutilement le scanner avec des manipulations et des vérifications supplémentaires. Nous définirons le langage d'analyse en ajoutant un autre paramètre dans le fichier de configurationVoici quelques réponses d'un des représentants des développeurs de SonarQube, confirmant ce fait. Sonar... sonar.language=ts ...
Mais tout fonctionnait, allez-vous vous opposer. Oui, c'est vrai, essayons de "hacker" un peu.


S'il y a un support pour les fichiers .vue -.
-files -files-fichiers SonarAlors, essayons de lui dire de les considérer comme TypeScript.
Ajoutons un paramètre :
sonar-project.properties:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...Lançons le scanner :

Et voilà, tout est revenu à la normale, avec un seul profil uniquement pour TypeScript. C'est-à-dire que nous avons réussi à résoudre le problème de support VueJs+TS pour SonarQube.
Essayons d'aller plus loin et d'améliorer un peu les informations de couverture.
Qu'avons-nous fait jusqu'à présent :
- ajouté au projet Sonar-le scanner ;
- configuré Jest pour générer des informations sur la couverture ;
- configuré Sonar-le scanner ;
- résolu le problème de support -files-fichiers + TypeScript.
En plus de la couverture par des tests, il existe d'autres critères de qualité intéressants, comme la duplication de code et le nombre de lignes (qui participe au calcul des coefficients liés à la complexité du code) du projet.
Dans l'implémentation actuelle du plugin pour travailler avec , donc pourquoi solliciter inutilement le scanner avec des manipulations et des vérifications supplémentaires. Nous définirons le langage d'analyse en ajoutant un autre paramètre dans le fichier de configuration (SonarTS) ne fonctionnera pas CPD (Copy Paste Detector) et le comptage des lignes de code -files-fichiers.
Pour créer une situation synthétique de duplication de code, dupliquons simplement le fichier composant avec un autre nom, et ajoutons également dans le code main.ts une fonction vide et le dupliquons sous un autre nom. Pour vérifier la duplication comme dans -files, ainsi que dans .ts -les fichiers.
main.ts :
...
function name(params:string): void {
console.log(params);
}
...Pour cela, il est nécessaire de commenter temporairement la ligne de configuration :
sonar-project.properties:
...
sonar.exclusions=src/main.ts
...Redémarrons le scanner avec les tests :
yarn test && yarn run sonarNotre couverture va bien sûr baisser, mais cela n'est pas notre préoccupation pour le moment.
Dans le cadre de la duplication des lignes de code, nous verrons :

Pour la vérification, utilisons CPD-l'outil – jscpd:
npx jscpd src
Pour les lignes de code :

Cela pourrait être résolu dans les versions futures des plugins SonarJS(TS). Je tiens à noter qu'ils commencent progressivement à fusionner ces deux plugins en un seul SonarJS, ce qui, je pense, est correct.
Maintenant, je voudrais examiner l'option d'améliorer les informations de couverture.
Pour l'instant, nous voyons la couverture des tests en pourcentage, à l'échelle du projet, et par fichiers en particulier. Mais il est possible d'étendre cette mesure avec le nombre de unit-tests dans le projet, ainsi qu'en fonction des fichiers.
Il existe une bibliothèque qui sait Jest-convertir le rapport dans un format pour Sonar... sonar.language=ts ...
generic test data — .
Installons cette bibliothèque dans notre projet :
yarn add jest-sonar-reporterEt ajoutons-le à la configuration Jest:
package.json :
…
"testResultsProcessor": "jest-sonar-reporter"
…Maintenant, exécutons le test :
yarn testAprès quoi, un fichier sera créé à la racine du projet test-report.xml.
Utilisons-le dans la configuration Sonar... sonar.language=ts ...
sonar-project.properties:
…
sonar.testExecutionReportPaths=test-report.xml
…Et redémarrons le scanner :
yarn run sonarVoyons ce qui a changé dans l'interface Sonar... sonar.language=ts ...

Et rien n'a changé. En fait, Sonar ne considère pas les fichiers décrits dans le rapport Jest comme des fichiers unit-tests. Pour corriger cette situation, utilisons le paramètre de configuration Sonar sonar.tests, dans lequel nous indiquerons explicitement les dossiers contenant les tests (il n'y en a pour l'instant qu'un) :
sonar-project.properties:
…
sonar.tests=src/components/__tests__
…Redémarrons le scanner :
yarn run sonarVoyons ce qui a changé dans l'interface :

Nous avons maintenant vu le nombre de nos unit-tests et, en cliquant à l'intérieur, nous pouvons voir la répartition de ce nombre dans les fichiers du projet :

Conclusion
Ainsi, nous avons examiné l'outil d'analyse continue SonarQube. Nous avons intégré avec succès le projet écrit en VueJs+TS. Nous avons résolu certains problèmes de compatibilité. Nous avons amélioré la visibilité de l'indicateur de couverture des tests. Dans cet article, nous n'avons examiné qu'un des critères de qualité du code (peut-être l'un des principaux), mais SonarQube il prend également en charge d'autres critères de qualité, y compris les tests de sécurité. Mais toutes ces fonctionnalités ne sont pas entièrement disponibles dans la version community. L'une des fonctionnalités intéressantes et utiles est les intégrations SonarQube avec différents systèmes de gestion de code, comme GitLab et BitBucket. Pour éviter le merge pull(merge) requestdans la branche principale du référentiel en cas de dégradation de la couverture. Mais c'est une histoire d'un tout autre article.
PS : Tout ce qui est décrit dans l'article sous forme de code est disponible dans .
Seuls les utilisateurs enregistrés peuvent participer au sondage. , s'il vous plaît.
Utilisez-vous la plateforme SonarQube :
26,3%Oui5
15,8%Non3
15,8%J'ai entendu parler de cette plateforme et je veux l'utiliser3
10,5%J'ai entendu parler de cette plateforme et je ne veux pas l'utiliser2
0,0%J'utilise une autre plateforme0
31,6%J'en entends parler pour la première fois6
19 utilisateurs ont voté. 3 utilisateurs se sont abstenus.
Source : habr.com
