C17 EngineeringC17 Engineering
C17 Engineering
Entreprise de Service Numérique spécialisée en technologies .NET, Cloud et DevOPS
  • Qui sommes-nous ?
    • Notre histoire
    • Chiffres clés
    • Équipe
    • Nos valeurs
  • Nos expertises
    • Nos compétences
    • Exemples de missions
  • Nos formations
    • Blockchain Masterclass
    • TopCode
  • Nos publications
    • Nos livres blancs
    • Nos vidéos
      • Les tutos
      • Les conférences
  • Rejoignez-nous !
    • Une carrière chez C17e
    • Offres d’emploi
    • Politique RH
  • Blog
Menu back  
21/12/2016Leave a commentBlog, C17ArticlesBy Carlos Bruce

Les tests unitaires avec Angular Js

  1. Tester son code Angular
  2. Les avantages des tests unitaires
  3. Angular est conçu pour les tests unitaires
  4. Conclusion

Tester son code Angular

Angular est un framework javascript très répandu et de plus en plus utilisé dans le monde du web.

En tant que framework Javascript, Angular dispose de toute la panoplie des fonctionnalités nécessaires pour créer une application Web. Cependant étant donné qu’il n’y a pas de compilation, seul votre navigateur est capable de vous donner des informations sur les erreurs et ces informations ne sont malheureusement pas suffisantes pour déboguer quand on travail avec une technologie tel que Angular.

Plusieurs outils se sont bâtis autour d’Angular afin de mettre en place des tests unitaires d’une manière assez simple.Nous allons dans cet article voir comment mettre en place une application Angular couverte par des tests Unitaires.

Les avantages des tests unitaires

Les tests unitaires assurent l’orthogonalité de votre code

Nous dirons d’un code qu’il est orthogonal si il est facilement modifiable, en introduisant la notion de Tests Unitaires sur des fonctionnalités dédiées de votre application vous respecterez automatiquement la notion de séparation des préoccupations (SepartionOfConcerns).Il sera donc plus facile de modifier votre code ou de détecter d’éventuelles régressions.

Passer davantage de temps sur le coeur de votre Application

Une fois que toutes vos fonctionnalités de bases ont été implémentées et testées automatiquement par le biais de tests Unitaires, vous aurez plus de temps pour vous concentrez sur la partie algorithmique (métier) de votre application.

Les Tests Unitaires une base pour la documentation

La convention étant de donner des noms explicites ainsi que d’isoler les comportements de vos tests Unitaires, si votre code est repris par un autre développeur il pourra facilement savoir ce qu’il se passe dans vos méthodes juste en lisant les noms de vos tests unitaires et les résultats de ceux ci.

Angular est conçu pour les tests unitaires

Dans son architecture, AngularJS utilise plusieurs patrons de conception comme par exemple l’injection de dépendance ce qui rend la mise en place des Tests Unitaires facile. On peut ainsi aisément injecter les dépendances des objets que l’on veut tester et mocker leur comportement ou donnée.

Les outils disponibles :

Karma, Jasmine, Angular Mocks, Protractor, Mocha, Chai / Chai-as-promised, Sinon, Browserify, Partialify.

Comme vous pouvez le voir la liste d’outils disponibles pour faire des tests Unitaires est longue, nous allons nous concentrer sur les deux outils les plus fréquemment utilisés (Karma et Jasmine).

Ces deux outils, Karma (le testeur) et Jasmine (le Framework), nous offrent toutes les fonctionnalités dont nous avons besoin pour faire des tests Unitaires sur nos applications.

Comment ça marche ?

Comme nous pouvons le voir dans ce schéma nous allons utiliser Karma/Jasmine et notre code source Angular pour mettre en place nos tests unitaires.

Karma : est un outil qui à été sélectionné par l’équipe AngularJS, afin de tester les fonctionnalités de leur Framework. Ils ont testés Karma et dès lors l’ont recommandé. En plus de son adaptabilité facile avec Angular, Karma peut s’intégrer à un workflow, émuler et établir vos tests sur les différents navigateurs ainsi que sur smartphones et tablettes.

Jasmine : est un framework qui fournit des fonctionnalités permettant de tester Unitairement ses applications Javascript. Comme Karma, Jasmine est un Framework recommandé par l’équipe AngularJS.

Installation

  1. Install node.js
  2. Install Jasmine
  3. Install Karma

Installation de NPM

  1. Télécharger et installer NPM – Node Package Manager
  2. Une fois cette étape terminée, tapez la ligne de commande suivante afin de voir la version NPM installée
> npm ‐‐version
3.9.3

Installation de Jasmine

> npm install ‐g yo
> npm install ‐g bower
> npm install generator‐jasmine

Installation de Karma

> npm install ‐g karma
> npm install generator‐karma
> yo karma ‐‐test‐framework=jasmine

Exemple

L’utilisation du framework Jasmine est assez simple nous allons dans la suite de cet article tester une application angular dans un premier temps avec Jasmine, puis nous intégrerons Karma à notre projet.

Tout d’abord vous devez installer le Jasmine generator dans votre projet de test (Le dossier contenant vos sources)

  1. Placer le fichier .yo-rc.json à la racine du projet que vous voulez tester. Vous devez avoir un object {} vide à l’intérieur de ce fichier..
  2. Lancer la commande :
> yo jasmine 

Deux dossiers sont alors créés dans votre répertoire.

Dans cet exemple nous allons voir les bases. Pour plus d’informations et de détails rendez-vous sur le site de Jasmine => #jasmine

Ouvrez le répertoire “test”, vous verrez qu’il se compose d’un fichier index.html représentant l’interface qui permettra de voir les résultats de vos tests et le dossier “spec” qui contient les fichiers décrivant vos tests Unitaires.

Sources

test/index.html

<!doctype html>
<html>
  <head>
    <title>Jasmine Spec Runner</title>
    <link rel="stylesheet" href="../bower_components/jasmine‐core/lib/jasmine‐core/jasmine.css" />
  </head>
  <body>
    <script src="../bower_components/jasmine‐core/lib/jasmine‐core/jasmine.js"></script>
    <script src="../bower_components/jasmine‐core/lib/jasmine‐core/jasmine‐html.js"></script>
    <script src="../bower_components/jasmine‐core/lib/jasmine‐core/boot.js"></script>

    <script src="../lib/angular/angular.js"></script>
    <script src="../lib/angular/angular‐animate.js"></script>
    <script src="../lib/angular/angular‐route.js"></script>
    <script src="../lib/angular/angular‐touch.js"></script>
    <script src="../lib/angular/angular‐sanitize.js"></script>
    <script src="../lib/angular/angular‐mocks.js"></script>

    <!‐‐ include source files here... ‐‐>
    <script src="../testableModule.js"></script>
    <!‐‐ include spec files here... ‐‐>
    <script src="spec/test.js"></script>
  </body>
</html>

Voici en détail la page index.html, vous devrez ajouter toutes vos dépendances Angular ainsi que vos sources et les sources de vos tests Unitaires.

Ici mes fichiers sont : testableModule.js et tests.js

testableModule.js

// Create module
var myApp = angular.module('myApp', []);

// Controller which counts changes to its "name" member
myApp.controller('MyCtrl', ['$scope', function ($scope) {
  $scope.name = 'Freeza';
  $scope.counter = 0;
  $scope.ChangeName = function (newName) {
    $scope.name = newName + " modified by function";
  }
  $scope.$watch('name', function (newValue, oldValue) {
    $scope.counter = $scope.counter + 1;
  });
}]);

// Controller with dependencies on Angular's $http service
myApp.service('MyService', function ($http) {
  // Returns the result with the response status
  //If you you to make an efficient test you should know the return value in advance
  this.get= function (id) {
    return $http.get('https://jsonplaceholder.typicode.com/posts/' + id).then(
      function(result) {
        if (result.status == 200) {
          return result;
        }
      }
    );
  };
});

tests.js

describe('myApp', function () {
  var scope,controller;
  beforeEach(function () {
    module('myApp');
  });

  describe('Unit : Testing Controller  MyCtrl', function () {
    beforeEach(inject(function ($rootScope, $controller) {
      scope = $rootScope.$new();
      controller = $controller('MyCtrl', {
        '$scope': scope
      });
    }));

    it('sets the name', function () {
      expect(scope.name).toBe('Freeza');
    });

    it('watches the name and updates the counter', function () {
      expect(scope.counter).toBe(0);
      scope.name = 'Batman';
      scope.$digest();
      expect(scope.counter).toBe(1);
    });

    it('modifies the name with function, watches the name', function () {
      scope.ChangeName('Batman');
      expect(scope.name).toBe('Batman modified by function');
    });
  });

  describe('Unit : Testing Service MyService', function () {
    var successCallback, myService, $httpBackend, userResponse, errorCallback;
    userResponse = { "userId": 1,"id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    };

    beforeEach(inject(function(_MyService_,_$httpBackend_) {
      angular.module('myApp');
      myService = _MyService_;
      $httpBackend = _$httpBackend_;
      successCallback = jasmine.createSpy();
      errorCallback = jasmine.createSpy();
    }));

    it('should contain a MyService service', (function() {
      expect(myService).toBeDefined();
    }));

    it('should returns http requests response with status and data of the User with UserId = 1', function () {
      var UserId = 1;
      $httpBackend.expectGET('https://jsonplaceholder.typicode.com/posts/' + UserId).respond(200, userResponse);
      myService.get(UserId).then(function(data) {
        expect(data.status).toEqual(200);
        expect(data.data).toEqual(userResponse);
      });
      $httpBackend.flush();
    });
  });
});

Page résultat

Karma

Installation des navigateurs

> npm install karma‐firefox‐launcher
> npm install karma‐chrome‐launcher
> npm install karma‐opera‐launcher
> npm install karma‐ie‐launcher

Installation de Karma dans votre projet

> karma init

Définir la configuration de Karma (vous pouvez saisir les mêmes valeurs) :

Modification du fichier de configuration de Karma

Nous allons modifier ce fichier comme suit :

files: [
  './lib/angular/angular.js',
  './lib/angular/angular‐mocks.js',
  './lib/angular/angular‐route.js',
  './test/spec/*.js',
  '*.js'
],
// Add this part if doesn't exist !Which plugins to enable
plugins: [
  'karma‐phantomjs‐launcher',
  'karma‐jasmine',
  'karma‐chrome‐launcher',
  'karma‐firefox‐launcher',
  'karma‐opera‐launcher',
  'karma‐ie‐launcher',
],
browsers: ['Chrome','Firefox']

Lancez vos tests :

> karma start ‐‐single‐run

Visual Studio et Karma

Après avoir créé votre projet sous Visual Studio, placez vous à la racine de votre projet puis installer Node Js avec la ligne de commande suivante :

> npm init

Vous verrez qu’un fichier package.json sera ajouté dans votre solution, vous devrez peut-être avoir à l’inclure manuellement via l’explorateur sous Visual Studio.

Vous pouvez procéder ainsi :

  1. Copier karma_conf.js à la racine de votre projet. (N’oubliez pas de modifier vos chemins d’accès)
  2. Copier le repertoire test à la racine de votre projet.
  3. Placer les fichiers contenant vos sources à tester , ici testableModule.js dans le répertoire www/scripts.
  4. Modifier le fichier package.json comme suit :
{
  "name": "testangular",
  "version": "1.0.0",
  "dependencies": {
  },
  "description": "",
  "repository": {
    "type": "git",
    "url": "https://github.com/karma‐runner/gulp‐karma"
  },
  "bugs": {
    "url": "https://github.com/karma‐runner/gulp‐karma/issues"
  },
  "homepage": "https://github.com/karma‐runner/gulp‐karma",
  "devDependencies": {
    "karma": "^0.13.0",
    "karma‐jasmine": "^0.3.6",
    "karma‐firefox‐launcher": "^1.0.0",
    "karma‐chrome‐launcher": "^2.0.0",
    "karma‐opera‐launcher": "^1.0.0",
    "gulp": "^3.9.0"
  }
}

5. Création d’un fichier gulpfile.js

Ici nous allons définir une tâche pour l’exécution de nos tests unitaires, il faut noter que gulp offre d’autres types de tâches telles que la minification/concaténation …

// <binding BeforeBuild='testangular' />
var gulp = require('gulp');
var Server = require('karma').Server;

// Run test once and exit
gulp.task('testangular', function (done) {
  new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true
  }, done).start();
});

Lancez vos tests sous Visual Studio

Une fois le fichier gulpfile.js créé et initialisé comme vu précédemment. Dans Visual Studio allez dans the Affichage > Autres fenêtres > Explorateur d’exécution de tâche.

Voici ce que vous devriez voir apparaître (la liste des tâches configurées dans votre fichier gulpfile.js)

Conclusion

Que pensez vous des tests Unitaires ?
Pensez-vous que vos applications angular seraient plus robustes si vous les testiez Unitairement ?
Auriez vous d’avantages d’informations à ajouter à cet article ?

Envoyez nous un email ou laissez un commentaire pour nous faire part de vos impressions..

angular jsc17gulpjasminekarmatests unitairesunit testingvisual studio
Plus d'articles
C17 sur YouTube !
07/10/2019
C’est parti pour le Challenge Cooptation !
02/09/2019
La cooptation, quésaco ?
26/08/2019
RDV au dernier bar avant la fin du monde
09/08/2019
Atelier technique CQRS + Event Sourcing
06/08/2019
Mentoring meeting #2
10/07/2019
Leave Comment

Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

clear formSubmit

Recent Posts
  • C17 sur YouTube !
  • C’est parti pour le Challenge Cooptation !
  • La cooptation, quésaco ?
  • RDV au dernier bar avant la fin du monde
  • Atelier technique CQRS + Event Sourcing
Categories
  • Blog
  • C17Articles
  • C17Events
  • C17Life
  • Christophe Persico

    Directeur commerial

    E-mailLinkedin
  • Pierre Murasso

    Fondateur, Directeur Technique

    E-mailLinkedin
  • Jonathan Behar

    Fondateur, Directeur Associé

    E-mailLinkedin
Tags
.NET .NET Core .Net Standard afterwork angular angular 2 angular js animation application aps .net core asp.net azure c17 cloud core Core CLI Core CLR Core FX css docker ecmascript fullstack full stack game gulp initiation jasmine javascript js karma laser Linux microsoft PCL popin popup responsive soirée target team building tests unitaires type typsecript unit testing visual studio
Les derniers articles du blog
  • C17 sur YouTube !
    07/10/2019
  • C’est parti pour le Challenge Cooptation !
    02/09/2019
  • La cooptation, quésaco ?
    26/08/2019
  • RDV au dernier bar avant la fin du monde
    09/08/2019
Ecrivez-nous

Submitclear

C17 Engineering
98, avenue du Général Leclerc
92100 Boulogne Billancourt

​01 41 13 64 70

Transports
Métro : Ligne 9 - Station Billancourt
Tram : T2 - Station Pont de Sèvres
Bus : 160/169/171/179/279/291/389


Siège social : 14, rue Beffroy 92200 Neuilly sur Seine

Find us on:

FacebookYouTubeLinkedin
C17 Engineering
All rights reserved - @C17 ENGINEERING 2019