19 Août 2016

Utiliser Webpack avec AngularJS – Partie 2

Etape 2 : les tests

Rappel des épisodes précédents

Dans mon précédent article Utiliser Webpack avec AngularJS – Partie 1, j’expliquais ce qu’est Webpack, à quoi il sert et comment créer une première application AngularJS en bundle.

Pour rappel, Webpack est un outil permettant de nous sortir de nos task-runners gulp ou grunt et qui  propose certaines fonctionnalités comme :

  • disposer de toutes les ressources statiques en tant que module,
  • intégrer et consommer des bibliothèques tierces très simplement en tant que module,
  • séparer votre build en plusieurs morceaux, chargés à la demande,
  • adapté pour les gros projets.

Pour bien commencer, je vous propose de partir directement des sources de la première partie présentes sur Github : Webpack-starter/Step1.

Petit aparté

Voyons un peu l’état de notre configuration Webpack :

Tout ceci est bien pour un environnement de développement mais beaucoup moins pour un environnement de production.

Normalement, si tout s’est bien passé, nous devrions avoir ces tâches dans notre configuration npm :

Tout d’abord, dans notre configuration webpack, récupérons le nom de la task lancée :

Nous savons donc la tache npm “build” correspond à notre production. Expliquons le à notre webpack :

Maintenant, il va falloir rendre notre configuration un peu plus dynamique. Le JSON n’est donc plus d’actualité. Changeons le en méthode, ce qui nous donne ceci :

Pour l’instant, rien de spécifique à un environnement de production, corrigeons donc ça avec la première chose à faire : minifier (juste avant le return).

Ajoutons aussi une petite fonctionnalité bien pratique : le changement de nom de fichier à chaque build. Cela permet d’éviter d’éventuels soucis de cache. Remplaçons donc le bloc ‘output’

Dans le cadre de la build, webpack générera un bundle du type ‘app.66867a6d2f12b5c521f0.js’ où la partie hash changera à chaque build.

Par contre, un problème se pose : que se passe-t-il quand nous enchaînons les builds? Effectivement, nous aurions plusieurs ‘app.*.js’…

Il nous faut donc cleaner le répertoire de destination avant de générer notre site. Utilisons donc le plugin ‘CleanWebpackPlugin’


Profitons-en aussi pour inclure nos source-map selon l’environnement.

Ceci aidera grandement en cas de bug et termine notre aparté.

Nous pouvons donc (enfin?) passer au vif du sujet : configurer Karma pour nos tests unitaires !

Configuration de Karma avec Webpack

Commençons par installer les modules npm pour Karma et Jasmine :

Puis ajoutons le connecteur karma-webpack

Pour ne pas avoir à ajouter chaque fichier de test dans la configuration Karma, je vous propose d’ajouter un fichier ‘tests.webpack.js’ dans le répertoire ‘src’ :

Ce petit bout de code permet de référencer directement angular et angular-mocks mais aussi d’importer automatiquement chaque fichier ‘*.spec.js’.

Ceci permet de simplifier mais aussi de ne pas avoir à relancer karma lors d’ajout de fichiers.

Passons maintenant à la configuration Karma (karma.conf.js) :

Ajoutons les scripts npm pour lancer karma :

Tel quel, vous devriez pouvoir faire tourner Karma mais je conseille d’aporter quelques modifications spécifiques aux tests dans la configuration Webpack.

Déjà, il faut savoir si le process en cours correspond au test :

Avec Karma, pas besoin de point d’entrée

Ensuite, pour faciliter les corrections, utilisons un inline-source-map :

Pour finir cette phase de préparation, ajoutons un instrumenter pour le code coverage via webpack et babel.

 

Cette dernière petite modification permet aussi de décentraliser la configuration babel.

Nous voilà donc prêts pour écrire notre premier test unitaire !

Premiers tests

Bon, nous avons donc une application fonctionnelle et testable. Il ne nous reste qu’à tester notre Controller HelloWorld.

Créons un fichier ‘HelloWorldController.spec.js’ à coté du fichier qu’il testera, à savoir ‘HelloWorldController.js’

Ainsi, nous avons un fichier de tests basé sur un module Angular (le module HelloWorld créé dans HelloWorld.js et injecté depuis notre main.js).

Initions maintenant le module via :

Ceci nous déclare le module spécifiquement pour tests, permettant ainsi d’utiliser les fonctions d’injection d’angular mocks.

De quoi avons nous besoin tester notre controller? D’une méthode d’exécution du controller ainsi que de sa dépendance. Souvenez-vous, nous utilisons ‘$scope’ dans notre controller.

Vous aurez remarqué que nous n’injectons pas le $scope directement, nous en créons un depuis le $rootScope. Ceci est logique puisqu’il ne sagit pas d’une vraie application Angular (pas d’exécution de template).

Pour tester et exécuter notre controller, il suffit donc d’utiliser la méthode $controller en injectant notre scope créé avant chaque test:

Nous y sommes : il ne reste qu’à tester les deux propriétés de notre controller. Ce qui nous donne au final :

Vous voilà prêts à pratiquer le Test Driven Development 😉

Sources et suite…

Nous en sommes aux deux tiers de notre tutoriel AngularJS/Webpack, il ne reste qu’une ultime étape : routing & lazy loading ! Lors de ce dernier épisode, nous apprendrons à utiliser quelques composants bien pratiques comme Angular UI-Router, OC Lazy Loading ainsi que le HotModuleReplacement de Webpack.

En attendant, les sources sont disponibles sur GitHub.

 

Bons tests et à bientôt !

Share
  • Salim Chami

    Bonjour, Merci pour cet article intéressant !
    J’aurais une question concernant les inclusions de templates avec webpack. Comment vous feriez pour les ng-include ?

    • Benoit FONTAINE

      Bonjour,
      Pour que ça fonctionne, il faudrait utiliser conjointement le file-loader et html-loader.
      Au pire, il reste le copy-webpack-plugin…