AngularJS est la meilleure chose qui soit arrivée à JavaScript depuis jQuery. C’est ainsi que le développement JavaScript a toujours été prévu. L’un des principaux avantages d’Angular est son injection de dépendances (Dependency Injection), très pratique pour les tests unitaires de code. Mais ce qui est un peu bizarre, c'est que je ne trouve pas de tutoriel sur la façon de faire des tests unitaires.
Bien sûr, il existe de nombreuses bonnes recommandations : utiliser le framework de test Jasmine et l'exécuteur de test Karma (Test Runner) ; mais il n'existe pas de tutoriel complet sur la façon de tester à partir de zéro ; J'ai donc écrit cet article. J’ai trouvé de nombreuses ressources en ligne pour comprendre comment procéder, et vous n’avez pas besoin de faire quoi que ce soit de tout cela maintenant (si vous lisez cet article en premier lieu).
Veuillez me signaler toutes les erreurs que vous voyez jusqu'à ce que je puisse dire qu'il s'agit de la meilleure pratique pour tester les applications angulaires basées sur Karma et Jasmine.
Présentation
Cet article vous guidera pour installer tous les outils dont vous avez besoin pour utiliser Karma et Jasmine pour les tests automatisés. Peu m'importe si vous utilisez réellement TDD (Test Driven Development) ou TAD (Test Assisted Development), pour les besoins de cet article, je suppose que vous avez déjà un fichier à tester.
Installer Karma
Si Node.js n'est pas installé, veuillez le télécharger et l'installer vous-même. Après l'installation, ouvrez un terminal ou une ligne de commande et entrez la commande :
npm install -g karma
Structure des fichiers
La structure des fichiers n'est pas étroitement liée à notre sujet, mais dans les tests suivants, la structure des fichiers que j'ai utilisée est la suivante :
Application | angular.js | angular-resource.js | Home | home.js | Tests | Home | home.tests.js | karma.config.js (will be created in the next step) | angular-mocks.js
*Je ne préconise pas cette structure de document, je la montre juste à titre d'exemple de test.
Configurer Karma
Basculez vers le répertoire où vous souhaitez placer le fichier de configuration, puis saisissez la commande suivante dans le terminal pour créer le fichier de configuration :
karma init karma.config.js
Quelques questions vous seront posées, notamment quel framework de test vous souhaitez utiliser, si vous avez besoin de fichiers de surveillance automatique, quels tests et fichiers testés sont inclus, etc. Dans notre tutoriel, nous conservons « Jasmine » comme framework par défaut, activons la détection automatique des fichiers et incluons les fichiers suivants :
../*.js ../**.*.js angular-mocks.js **/*.tests.js
Ce sont des chemins relatifs, comprenant 1) tous les fichiers .js du répertoire parent, 2) tous les fichiers .js dans tous les sous-répertoires du répertoire parent, 3) angulaire-mock.js dans le répertoire actuel, 4) Et tous Fichiers .tests.js dans le répertoire actuel (y compris les sous-répertoires) (j'aime ainsi distinguer les fichiers de test des autres fichiers).
Quels que soient les fichiers que vous choisissez, assurez-vous d'inclure angulaire.js, angulaire-mock.js et les autres fichiers que vous devez utiliser.
Démarrer le Karma
Vous pouvez maintenant démarrer Karma, entrez toujours dans le terminal :
karma start karma.config.js
Cette commande lancera les navigateurs que vous avez répertoriés dans le fichier de configuration sur votre ordinateur. Ces navigateurs se connecteront à l'instance Karma via des sockets. Vous verrez une liste des navigateurs actifs et serez informé s'ils exécutent des tests. J'aurais aimé que Karma vous donne un résumé des résultats finaux des tests sur chaque navigateur (par exemple 15 sur 16 réussis, 1 échoué), mais malheureusement vous ne pouvez voir ces informations que via la fenêtre du terminal.
L'une des fonctionnalités les plus remarquables de Karma est que vous pouvez vous connecter et tester votre code en utilisant n'importe quel appareil du réseau. Essayez de pointer votre navigateur mobile vers le service Karma. Vous pouvez trouver l'URL de test dans n'importe quel navigateur exécuté sur votre ordinateur. Cela devrait ressembler à : http://localhost:9876/?id=5359192. Vous pouvez pointer le navigateur de votre téléphone, machine virtuelle ou tout autre appareil vers [votre adresse IP sur le réseau] :9876/?id=5359192. Étant donné que Karma exécute une instance Node.js, votre machine de test ressemble à un site Web. serveur, les tests seront envoyés à tout navigateur pointé vers lui.
Tests de base
Nous supposons que vous avez déjà un fichier à tester. Le fichier home.js que nous souhaitons utiliser est le suivant :
home.js
'use strict'; var app = angular.module('Application', ['ngResource']); app.factory('UserFactory', function($resource){ return $resource('Users/users.json') }); app.controller('MainCtrl', function($scope, UserFactory) { $scope.text = 'Hello World!'; $scope.users = UserFactory.get(); });
Nous pouvons créer nos cas de test dans le fichier home.test.js. Commençons par le test simple : $scope.text devrait être égal à « Hello World ! ». Afin de terminer ce test, nous devons simuler notre module Application et la variable $scope. Nous ferons cela dans la méthode beforeEach de Jasmine afin d'avoir un tout nouveau contrôleur (propre) et un objet scope au début de chaque scénario de test.
home.tests.js
'use strict'; describe('MainCtrl', function(){ var scope; //我们会在测试中使用这个scope //模拟我们的Application模块并注入我们自己的依赖 beforeEach(angular.mock.module('Application')); //模拟Controller,并且包含 $rootScope 和 $controller beforeEach(angular.mock.inject(function($rootScope, $controller){ //创建一个空的 scope scope = $rootScope.$new(); //声明 Controller并且注入已创建的空的 scope $controller('MainCtrl', {$scope: scope}); }); // 测试从这里开始 });
Vous pouvez voir dans le code que nous injectons notre propre scope afin de pouvoir valider ses informations en dehors de celui-ci. N’oubliez pas non plus de vous moquer du module lui-même (ligne 7) ! Nous sommes maintenant prêts pour les tests :
home.tests.js
// 测试从这里开始 it('should have variable text = "Hello World!"', function(){ expect(scope.text).toBe('Hello World!); });
如果你运行这个测试,它可以在任何指向Karma的浏览器中执行,并且测试通过。
发送$resource请求
现在我们已经准备好测试 $resource 请求。要完成这个请求,我们需要使用到 $httpBackend, 它一个模拟版本的Angular $http。我们会创建另一个叫做 $httpBackend 的变量,在第二个 beforEach块中,注入 _$httpBackend_ 并将新创建的变量指向 _$httpBackend_。接下来我们会告诉 $httpBackend 如何对请求做出响应。
$httpBackend = _$httpBackend_; $httpBackend.when('GET', 'Users/users.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]);
我们的测试: home.tests.js
it('should fetch list of users', function(){ $httpBackend.flush(); expect(scope.users.length).toBe(2); expect(scope.users[0].name).toBe('Bob'); });
都放到一起
home.tests.js
'use strict'; describe('MainCtrl', function(){ var scope, $httpBackend; //we'll use these in our tests //mock Application to allow us to inject our own dependencies beforeEach(angular.mock.module('Application')); //mock the controller for the same reason and include $rootScope and $controller beforeEach(angular.mock.inject(function($rootScope, $controller, _$httpBackend_){ $httpBackend = _$httpBackend_; $httpBackend.when('GET', 'Users/users.json').respond([{id: 1, name: 'Bob'}, {id:2, name: 'Jane'}]); //create an empty scope scope = $rootScope.$new(); //declare the controller and inject our empty scope $controller('MainCtrl', {$scope: scope}); }); // tests start here it('should have variable text = "Hello World!"', function(){ expect(scope.text).toBe('Hello World!'); }); it('should fetch list of users', function(){ $httpBackend.flush(); expect(scope.users.length).toBe(2); expect(scope.users[0].name).toBe('Bob'); }); });
技巧
Karma会运行所有文件中的所有测试用例,如果你只想运行所有测试的一个子集,修改 describe 或 it 为 ddescribe 或 iit 来运行个别的一些测试。如果有些测试你不想运行他们,那么修改 describe 或 it 为 xdescribe 或 xit 来忽略这些代码。
你也可以在html文件的页面上运行你的测试。举例的代码如下:
home.runner.html
<!DOCTYPE html> <html> <head> <title>Partner Settings Test Suite</title> <!-- include your script files (notice that the jasmine source files have been added to the project) --> <script type="text/javascript" src="../jasmine/jasmine-1.3.1/jasmine.js"></script> <script type="text/javascript" src="../jasmine/jasmine-1.3.1/jasmine-html.js"></script> <script type="text/javascript" src="../angular-mocks.js"></script> <script type="text/javascript" src="home.tests.js"></script> <link rel="stylesheet" href="../jasmine/jasmine-1.3.1/jasmine.css"/> </head> <body> <!-- use Jasmine to run and display test results --> <script type="text/javascript"> var jasmineEnv = jasmine.getEnv(); jasmineEnv.addReporter(new jasmine.HtmlReporter()); jasmineEnv.execute(); </script> </body> </html>