L’intégration continue hors Java

L’intégration continue est un élément essentiel dans le contexte d’industrialisation des développements. Depuis l’arrivée de Maven il y a 10 ans, les solutions se sont perfectionnées, principalement dans le monde Java. Cependant, ces principes sont globalement valables pour d’autres motorup.com.au langages et sont à présent repris dans le domaine très dynamique du client riche et du multicanal. On constate que les différents outils mis en œuvre deviennent des standards, déclinés dans les différentes technologies ou intégrés via des plugins additionnels.

Après un bref rappel des principes de l’intégration continue, nous listerons les outils disponibles pour chaque technologie majeure, afin d’en mesurer la maturité et outerspaces.com.au le niveau d’adoption.

Principes

Les outils nécessaires à l’intégration continue couvrent les aspects suivants :

  • tests unitaires
  • statistiques et complexité du code
  • qualité du code
  • couverture des tests
  • tests fonctionnels/d’intégration
  • production de documentation

Ces outils sont mis en œuvre (contrôle, récupération des résultats) au travers d’outils de build puis de supervision (tableaux de bord). De plus les tests peuvent nécessiter une exécution dans un container spécifique (container web, emulateur natif ou mock), surtout quand l’interface graphique est en jeu.

Les interactions entre les différents outils sont de plus en plus complexes (couches d’abstraction de plus en plus nombreuses). Le schéma suivant illustre les différentes possibilités :

PHP

Comme Java, PHP est une technologie éprouvée qui bénéficie d’outils adaptés depuis des années. Toutefois, ils sont moins sophistiqués que ceux pour Java et la pratique de l’intégration continue dans son ensemble est moins répandue.

  • Tests unitaires : PhpUnit est un dérivé de JUnit (fait partie de ce qu’on appelle les xUnit).
  • Statistiques sur le code (nombre de fichiers, répertoires, classes abstraites, méthodes, lignes de commentaires) : PHPLoc
  • Complexité cyclomatique, identification des parties de l’application à refactorer : PHPDepend
  • Détection de code inutilisé, qualité du code, bugs : PHPMessDetector
  • Recherche de code inutilisé : Phpdcd (PHP Dead Code Detector)
  • Vérification de conventions de codage selon différents frameworks (Zend, PEAR, Symphony) : PhpCodeSniffer
  • Détection des redondances de code (copier-coller) : PHPCopyPasteDetector
  • Détection de code « obscur », anti-pattern, ou source d’erreur : Padawan
  • Couverture des tests : Clover
  • Tests fonctionnels / UI : Selenium (solution multi-technologies)
  • Génération de documentation : PhpDocumentor

Une déclinaison de Maven pour PHP est disponible et gère de très nombreux aspects :

  • Propose des archétypes pour le développement de bibliothèques (lib) et de projets web
  • Packaging de type phar
  • Vérification de la syntaxe lors du build, via php.exe
  • Intégration des rapports phpUnit et de couverture de code (php-unitcoverage)
  • Intégration de php-documentor
  • Gestion des dépendances aux bibliothèques PHP (archives phar) via le plugin maven-php-dependency
  • Gestion de la structure de projets basés sur Zend
  • Pas encore d’intégration avec Clover, PHPLoc, Pdepend, PHPMD, PhpCodeSniffer

http://www.php-maven.org/

On trouve également un plugin pour CruiseControl, phpUnderControl (inclut PHPUnit, PhpMD, Clover, CodeSniffer), et un plugin pour Sonar.

C/C++

L’environnement C/C++, qui connaît un regain d’intérêt via les SDK mobiles natifs (iOS / Objective-C utilisant un runtime C) et des projets comme Chromium et LLVM, propose les outils d’analyse statique de base :

  • Tests unitaires : CppUnit, GoogleTest (utilisé pour projets Chromium et LLVM)
  •  Métriques/statistiques sur le code : CCCC (C/C++ Code Counter)
  • Analyse qualitative du code : un plugin pour Sonar est disponible.

Un plugin pour Maven est également proposé. Il gère notamment le packaging et les dépendances :

  • Packaging en archives de type nar, avec cycle dédié
  • Compilation de code C, C++, sur différentes architectures, avec différents compilateurs/linkers. Les archives peuvent être indépendantes de la machine, ou on peut préciser l’environnement via des options.
  • Étapes nar-validate et nar-download : la première vérifie la présence du linker et d’un compilateur associé, et la seconde télécharge les dépendances (nar).
  • Une section near-dependencies permet de définir les dépendances (archives nar ou jars – pour tests de projets mixtes utilisant JNI ou Java HL).
  • Gestion des ressources Gnu et des commandes make, compile, process.

http://duns.github.io/maven-nar-plugin/

  • Tests unitaires (mais n’utilise pas CppUnit).

C#/.NET

Les outils d’intégration continue pour .NET sont propriétaires Microsoft (intégrés à Visual Studio, suivant la version). On ne bénéficie donc pas de standards comme les xUnit, Maven, ni de l’intégration Jenkins via plugin. Cependant un plugin pour Sonar est disponible.

  • Tests unitaires : MsTest
  • Analyse de code (conventions) : Static Code Analysis ou plugin pour Sonar
  • Tests UI : Web Tests (dans versions Tester et Team suite)
  • Ordered Tests (tests ordonnés) pour versions Developper, Tester, Team suite
  • Automatisation de tâches (compilation, déploiement) : MsBuild et Team Foundation Build (intégré à Team Foundation Server), équivalents de Maven mais en moins abouti et moins extensible (disponibles depuis Visual Studio 2005).

Javascript

La prise en charge de l’intégration continue pour Javascript, bien qu’apparue tardivement, est très dynamique et très complète :

  • Tests statiques/unitaires : jsUnit (mais complexe à mettre en œuvre et obsolète, on lui préférera Jasmine, orienté BehaviourDriverDevelopment – mais syntaxe différente de JUnit).
  • Qualité du code (conventions de codage) : JSLint ou JSHint (fork de jsLint)
  • Tests d’intégration/UI : QUnit (tests jQuery), Selenium (gère divers frameworks UI et peut être intégré à Jenkins via un plugin).
  • PhantomJS est un container WebKit utilisable en ligne de commande (hors d’un navigateur), permettant l’intégration de tests depuis une chaîne Maven (il s’intègre avec QUnit ou Jasmine).
  • Plateformes pour le développement orienté tests (TDD) :
  • JsTestDriver est une plateforme pour le développement orienté tests (TDD). Il utilise la syntaxe JUnit et s’intègre avec Jasmine, QUnit et Jenkins.
  • TestSwarm est une plateforme TDD distribuée. Les rapports peuvent être convertis au format xUnit. Il s’intègre avec QUnit et Jenkins.
  • Génération de documentation : Doxygen.

Un plugin pour Sonar permet d’importer les rapports JsTestDriver. Il ne fournit cependant pas les informations de taux de réussite et de couverture du code.

L’intégration avec maven se fait au moyen de plusieurs plugins dédiés :

  • archétypes pour les projets javascript de base et pour les projets utilisant JQuery (structures des répertoires, POM préconfiguré pour ressources et plugins)

https://github.com/akquinet/javascript-archetypes

  • plugin javascript-maven-plugin : gère les ressources et les dépendances via js-import, les tests unitaires via jsLint, les tests d’intégration/UI via QUnit et JS Test Runner, la génération de documentation via jsdoc.

http://mojo.codehaus.org/javascript-maven-tools/
http://mojo.codehaus.org/javascript-maven-tools/javascript-maven-plugin/

  • plugin jstools : permet d’utiliser jslint et jsdoc
  • plugins pour des étapes spécifiques du cycle Maven :
  • plugin Maven pour jasmine
  • plugin jstools qui permet d’utiliser jslint et jsdoc
  • plugin pour yuicompressor (compression et obfuscation de code js et css)
  • Voir également les plugins pour jsMin, Google Closure compressor, UglifyJs, Dojo Shrinksafe, JSON Compression.
  • plugin pour jsTestDriver (jstd-maven-plugin).

Android

La partie analyse statique et qualitative du code est déjà gérée par les outils standards Java. L’intégration spécifique à Android concerne donc le packaging et le lancement de tests d’intégration/UI.

Les tests d’intégration/UI peuvent être lancés :

  • dans l’émulateur Android : deux applications sont nécessaires, celle à tester et celle de test. On utilise robotium.
  • hors de l’émulateur Android : on utilise un mock, roboelectric.

Un plugin pour gérer l’Android Emulator est proposé pour Hudson/Jenkins.

Des archétypes Maven sont proposés : projet simple avec tests unitaires, projet avec tests d’intégration projet multi-modules pour la release sur le marketplace.

Le build maven peut être effectué :

  • soit en utilisant la tâche Ant de base fournie (mais ne gère pas les dépendances et n’est pas facilement extensible)
  • soit via le plugin android-maven-plugin : gère les dépendances et les étapes spécifiques au build Android (et utilise les plugins Maven standards pour les étapes classiques), permet l’intégration avec Eclipse (m2e-android).

http://stand.spree.de/wiki_details_maven_archetypes

http://code.google.com/p/robotium/

https://wiki.jenkins-ci.org/display/JENKINS/Android+Emulator+Plugin

iOS

XCode, propose deux types de targets pour les tests : application test target (lancés dans le simulateur ou le device) et logic test target (tests unitaires, uniquement classes, en dehors du simulateur/device).

Le lancement de tests « applicatifs » (fonctionnels/UI) n’est pas supporté hors XCode, mais une solution est proposée (Running Kiwi Specs from the Command Line) :

http://9elements.com/io/index.php/continuous-integration-of-ios-projects-using-jenkins-cocoapods-and-kiwi

  • Tests unitaires : Kiwi est l’équivalent de JUnit. OCUnit2JUnit permet de convertir les résultats de tests vers le format JUnit.
  • Analyse de code statique (statistiques) : SLOCCount.
  • Qualité de code : pas d’équivalent de PMD, mais OCLint (basé sur parcours AST).
  • Couverture de code : via option GCOV de gcc.
  • Tests UI/fonctionnels : framework Frank. Une version spéciale est nécessaire pour qu’il quitte le simulateur iOS à la fin des tests.
  • Gestion de packages et dépendances : CocoaPods est un équivalent de Maven.
  • Intégration avec Sonar

Pas d’intégration initiale, agrégation des résultats à gérer via scripts pre/post depuis les jobs Hudson. Un plugin Sonar récent est proposé par Octo.

  • Intégration avec Jenkins

Un plugin Xcode Integration est proposé pour Jenkins. Il permet de définir des étapes de type XCode dans les jobs. Pour ces jobs on précise la target Xcode.

  • Packaging/archivage et déploiement

Le framework TestFlight propose une target dédiée utilisable depuis Jenkins via le plugin Xcode. On sélectionne l’option « Build IPA » pour le job. L’upload vers le serveur de tests TestFlight doit cependant être effectué via curl, depuis un job free style.

  • Intégration avec Maven

Un plugin pour Xcode est disponible, il ne prend cependant en compte que le build, la gestion des dépendances et le déploiement des composants (pas le déclenchement des tests unitaires ou UI) :

Il propose 3 types de projets (packaging type dans pom) : Library, Framework, et App. Le type App permet de préciser une signature et plusieurs configurations (pour test interne, validation AppStore).
Les dépendances sont ajoutées automatiquement au build path du projet Xcode, d’après les entrées dependencies du pom (utilise le plugin resolve-pom-maven-plugin pour injecter les informations de versions).

https://github.com/fhelg/sonar-objective-c

http://ray.sh/posts/xcode-hudson-plugin/

https://testflightapp.com/

http://sap-production.github.io/xcode-maven-plugin/site/index.html

Matrice comparative

La grille d’évaluation ci-dessous évalue la maturité de l’intégration continue dans les différents environnements non Java, la complexité de mise en œuvre, le degré d’adoption par les développeurs, et le coût.

Conclusion

Ce tour d’horizon confirme la forte influence des pratiques et des outils en Java sur les autres technologies.

De nombreux frameworks de tests unitaires utilisent une syntaxe dérivée de JUnit.

La plateforme Jenkins/Hudson est utilisable pour la plupart des environnements grâce à des plugins, et les tâches génériques du cycle Maven ont souvent des correspondances dans les autres technologies (d’où la présence de plugins maven dédiés).

Les tests d’interfaces graphiques tendent à remplacer les test de services basés sur des clients de webservices : les WebView permettent de déclencher des actions utilisateur et de récupérer les résultats. La complexité vient cependant du besoin d’exécuter ces tests depuis la chaîne de build (en ligne de commande).

En général, la gestion des dépendances et versions n’est pas aussi aboutie qu’en Java.

Globalement, le sujet de l’intégration continue est plus dynamique pour les environnements web (javascript). L’interaction avec les containers natifs (émulateurs iOS et Android) est quant-à-elle plus complexe.

On note un intérêt bien moindre pour ces questions dans le domaine C/C++, malgré une légère progression grâce aux projets dynamiques LLVM et Chromium. L’environnement .NET reste lui fermé aux technologies propriétaires.

Quoi qu’il en soit, le sujet continue de progresser et on peut espérer un effort de standardisation sous l’influence des pratiques en Java.

Analyse et veille technologique , , , , , , , ,

Les commentaires sont fermés