Ir para o conteúdo
Usando Jasmine & Karma para escrever e executar testes de unidade para aplicativos AngularJS

Usando Jasmine & Karma para escrever e executar testes de unidade para aplicativos AngularJS

Aprenda a escrever testes de unidade com jasmine, como executá-los com karma e como criar proxies de controles AngularJS como filtro, controlador e muito mais.

11min read

Observação: embora digamos que este post mostrará como usar o Visual Studio para escrever aplicativos AngularJS e testes de unidade, você pode usar esses métodos para configurar ambientes de teste para qualquer IDE.

Neste post abordaremos os seguintes tópicos:

  • Configurando o ambiente de desenvolvimento
  • Configurando o ambiente de teste para jasmim
  • Setting up the karma test runner environment
  • Escrevendo o teste de unidade para filtro, controlador e serviço

Usaremos o npm para instalar dependências e o Visual Studio para escrever código, e executaremos testes usando karma no prompt de comando. No final do post, devemos ter testes rodando conforme a imagem abaixo:

No final do post, devemos ter testes rodando conforme mostrado na imagem

So let’s get started!

Step 1

Crie um projeto de aplicativo Web ASP.NET no Visual Studio escolhendo o tipo de projeto de modelo vazio.

New ASP.NET Project - AngularTestDemp

Embora eu esteja criando um projeto AngularJS no Visual Studio, você pode criar um projeto usando qualquer IDE de sua escolha. A única coisa que você precisa ter em mente é que todos os comandos que executaremos aqui devem ser executados dentro da pasta raiz do projeto.

Step 2

Depois que o projeto for criado, inicie o prompt de comando como administrador e altere o diretório para a pasta raiz da pasta do projeto criado. No caso do Visual Studio, altere o diretório para a pasta do projeto, não para a pasta da solução.

Depois que o projeto for criado, inicie o prompt de comando como administrador e altere o diretório para a pasta raiz da pasta do projeto criado

Por exemplo, a estrutura de pastas que estou usando é a seguinte:

  • AngularJSUnitTestDemo : Solution Folder
  • AngularJSUnitTestDemo : Pasta raiz do projeto. Então, navegamos até aqui.

Step 3

Precisamos ter certeza de que o NodeJS está instalado na máquina. Se não estiver instalado, baixe-o e instale-o a partir do https://nodejs.org/en/. Podemos verificar se o NodeJS está instalado ou não executando o seguinte comando:

  • node –version 

Se obtivermos a versão do NodeJS como saída, o NodeJS será instalado na máquina.

 we get NodeJS version as output, then NodeJS is installed

Nesta etapa, instalamos e verificamos o NodeJS.

Step 4

Em seguida, vamos instalar o AngularJS no projeto. Existem várias maneiras de fazer isso (pacote NuGet, Bower etc.), no entanto, estou escolhendo o NPM para instalar o AngularJS no projeto. Para instalar, execute o comando npm conforme mostrado abaixo:

  •  npm install angular –save
nesta etapa, instalamos o AngularJS no projeto

Nesta etapa, instalamos o AngularJS no projeto.

Step 5

Agora vamos usar o executor de testes Karma para executar testes.  Saiba mais sobre o Karma aqui: https://karma-runner.github.io/1.0/index.html Criado pela equipe Angular, o Karma é um executor de testes baseado em especificações. Para instalar o Karma, execute o comando conforme mostrado abaixo:

  •  npm install -g karma –save-dev
Nesta etapa, instalamos o Karma no projeto.

Nesta etapa, instalamos o Karma no projeto.

Step 6

Vamos usar o Jasmine, estrutura de teste JavaScript orientada por comportamento para escrever testes de unidade. Saiba mais sobre Jasmine aqui: http://jasmine.github.io

Vamos instalar o Jasmine Core e o Jasmine Karma. Para instalá-los, execute o comando conforme mostrado abaixo:

  • npm install karma-jasmine jasmine-core –save-dev
Nesta etapa, instalamos o núcleo de jasmim e o plug-in de jasmim karma no projeto.

Nesta etapa, instalamos o núcleo de jasmim e o plug-in de jasmim karma no projeto.

Step 7

Usaremos o módulo ngMock para simular serviços, módulos, controladores, filtros e muito mais do AngularJS. Para usar o ngMock, precisamos instalar a biblioteca angular-mocks no projeto. Para fazer isso, execute o comando conforme mostrado abaixo:

  • npm install angular-mocks –save-dev
Nesta etapa, instalamos a biblioteca angular-mocks no projeto.

Nesta etapa, instalamos a biblioteca angular-mocks no projeto.

Step 8

O Karma nos permite executar testes em vários navegadores. Para fazer isso, precisamos instalar diferentes plug-ins do navegador. Neste exemplo, gostaria de executar um teste no Chrome, então vou instalar um plug-in do navegador Chrome da seguinte maneira:

  • npm install karma-chrome-launcher –save-dev
instalamos o iniciador de karma do navegador Chrome

Nesta etapa, instalamos o iniciador de karma do navegador Chrome. Se desejar, você também pode instalar outros lançadores de navegador.

Step 9

Podemos ter qualquer estrutura de pastas para o projeto de acordo com nossos requisitos de negócios. No entanto, para o propósito deste post, vou mantê-lo simples. Vou criar duas pastas: app e tests. A pasta do aplicativo manterá todos os arquivos de scripts Angular e a pasta de testes para manter todos os testes. Para criar essas pastas, execute os comandos conforme mostrado abaixo:

  • md app
  • Testes de MD

Step 10

Essa etapa só será necessária se você estiver trabalhando no Visual Studio, caso contrário, poderá ignorar esta etapa. Vamos adicionar todos os arquivos recém-instalados e a pasta recém-criada no projeto. Volte para o Visual Studio.

Nesta etapa, incluímos todos os nossos arquivos e pastas recém-criados no Visual Studio

Nesta etapa, incluímos todos os nossos arquivos e pastas recém-criados no projeto do Visual Studio.

Step 11

Nesta etapa, vamos adicionar novos arquivos ao projeto:

  • CalculatorApp.js to write AngularJS code. Add this file in app folder.
  • CalculatorAppTest.js escrever testes unitários para controlador, filtros, serviços escritos em CalculatorApp.js. Adicione este arquivo na pasta tests.
  • SpecRunner.html exibir os resultados do teste no navegador usando jasmim
  • Index.html, página html do aplicativo.

Para adicionar arquivos no Visual Studio,

  • Clique com o botão direito do mouse na pasta do projeto/aplicativo e adicione um arquivo chamado CalculatorApp.js
  • Clique com o botão direito do mouse na pasta do projeto/testes e adicione um arquivo chamado CalculatorAppTest.js
  • Clique com o botão direito do mouse no projeto e adicione um arquivo HTML chamado SpecRunner.html
  • Clique com o botão direito do mouse no projeto e adicione um arquivo HTML chamado index.html

Nesta etapa, adicionamos novos arquivos para escrever código, teste de unidade e exibir resultados de teste.

Step 12

Nesta etapa, vamos configurar SpecRunner.html. Isso renderizará os resultados do teste no navegador. Então, abra SpecRunner.html e adicione as seguintes referências.

Jasmine Test Results
    <meta charset="utf-8" />
    <link href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css" rel="stylesheet" />
    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>

    <script src="node_modules/angular/angular.js"></script>
    <script src="node_modules/angular-mocks/angular-mocks.js"></script>

    <script src="app/CalculatorApp.js">
    <script src="tests/CalculatorAppTest.js"></script>

Passo 13 – Escrevendo testes para o filtro AngularJS

Finalmente, chegamos à etapa em que escreveremos alguns testes! Vamos começar escrevendo testes para o filtro AngularJS. Adicione o seguinte teste a CalculatorAppTest.js.

describe('Calculator App Tests', function () {

    beforeEach(module('MyApp'));

    describe('reversestringfiltertest', function () {

        var reverse;
        beforeEach(inject(function ($filter) { //initialize filter
            reverse = $filter('reverse', {});
        }));

        it('Should reverse a string', function () { 
            expect(reverse('india')).toBe('aidni'); //pass test
            expect(reverse('don')).toBe('don'); //fail test
        });
    });
});

No trecho de código acima, estamos criando um proxy do módulo e filtro usando ng-mock. Escrevemos testes para o nome do filtro 'reverse' do módulo 'MyApp' e estamos injetando o filtro usando o serviço $filter do ng-mock.

Neste ponto, se formos em frente e executarmos o SpecRunner.html, obteremos um resultado de teste com falha porque não criamos o filtro AngularJS ou o módulo 'MyApp'.

Neste ponto, se formos em frente e executarmos o SpecRunner.html, obteremos um resultado de teste com falha porque não criamos o filtro AngularJS ou o módulo 'MyApp'

Então, agora vamos em frente e criar um módulo AngularJS 'MyApp' com filtro 'reverso'. Vamos criá-los no App/CalculatorApp.js

var MyApp = angular.module("MyApp", []);

MyApp.filter('reverse', [function () {
    return function (string) {
        return string.split('').reverse().join('');
    }
}]);

Agora volte e corra mais uma vez, corra SpecRunner.html. Vamos descobrir, mais uma vez o teste falhou. Como está mostrando na mensagem de falha de teste que - Esperado 'aceno' para ser 'don'

Vamos descobrir, mais uma vez o teste falhou. Como está mostrando na mensagem de falha de teste que - Esperado 'aceno' para ser 'don'

Se você se lembra, escrevemos deliberadamente um teste reprovado. Então, agora vamos corrigir o teste em CalculatorAppTest.js

describe('Calculator App Tests', function () {

    beforeEach(module('MyApp'));

    describe('reversestringfiltertest', function () {

        var reverse;
        beforeEach(inject(function ($filter) { //initialize filter
            reverse = $filter('reverse', {});
        }));

        it('Should reverse a string', function () { 
            expect(reverse('india')).toBe('aidni');
            expect(reverse('don')).toBe('nod'); 
        });
    });
});

Quando executarmos o teste no SpecRunner.html, descobriremos que todos os testes foram aprovados, conforme mostrado na imagem abaixo.

Nesta etapa, escrevemos um teste para o filtro AngularJS e o executamos usando o Jasmine SpecRunner.html.

Problems in running test using SpecRunner.html

Você deve ter notado que o único problema na abordagem acima é que cada vez que alteramos o código de teste ou o código-fonte, precisamos voltar e carregá SpecRunner.html novamente ou atualizá-lo manualmente para ver o resultado do teste atualizado. No desenvolvimento de projetos reais, isso pode ser uma dor. Precisamos de um mecanismo no qual, sempre que o código mudar, os testes sejam executados automaticamente. Para fazer isso, temos o executor de teste. Já instalamos o executor de teste Karma para executar testes automaticamente sempre que o código for alterado, então agora vamos configurá-lo para fazer isso.

Step 14

To configure Karma, we need to run command Karma init.

karma init
 configure Karma, we need to run command Karma init

Você será solicitado com muitas perguntas para responder, use as seguintes respostas, conforme exibido abaixo:

Você será solicitado com muitas perguntas para responder, use as seguintes respostas conforme exibido

Karma.cnf.js arquivo foi criado depois de responder a essas perguntas. Em seguida, vamos abrir o Visual Studio e incluir o arquivo recém-criado Karma.conf.js no projeto.  Abra Karma.conf.js e adicione referências de Angular e Angular Mock. Suas seções de arquivos devem ser semelhantes à imagem abaixo:

files: [
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'app/*.js',
      'tests/*Test.js'
    ],

Em seguida, volte para o prompt de comando e execute o comando

karma start 

Assim que executarmos o comando karma start, os testes começarão a ser executados e poderemos ver os resultados dos testes no prompt de comando, conforme mostrado na imagem abaixo.  À medida que você altera o código e salva o arquivo, o teste será executado automaticamente.

À medida que você altera o código e salva o arquivo, o teste será executado automaticamente

Step 15

Agora vamos escrever um teste de unidade para o controlador AngularJS. Adicione o teste a seguir a CalculatorAppTest.js e adicione um teste para o controlador abaixo ao teste de filtro ou abaixo do teste de filtro descrito.

describe('addcontrollertest', function () {
        var $controller;
        beforeEach(inject(function (_$controller_) {
            $controller = _$controller_;
        }));
        it('1 + 1 should equal 2', function () {
            var $scope = {};
            var controller = $controller('CalculatorController', { $scope: $scope });
            $scope.num1 = 1;
            $scope.num2 = 2;
            $scope.add();
            expect($scope.sum).toBe(3);
        });
    });

Estamos criando um proxy do controlador e injetando-o usando ng-mock $controller serviço.  Depois que o controlador for injetado, pegue a referência de CalculatorController (controlador no teste aqui) e chame o método add.  Neste ponto, o teste falhará, pois ainda não escrevemos o controlador.  O Karma está dando a mensagem de falha de que CalculatorController não é uma função.

Neste ponto, o teste falhará, pois ainda não escrevemos o controlador.  O Karma está dando a mensagem de falha de que CalculatorController não é uma função.

Em seguida, vamos em frente e escrever o controlador no módulo 'MyApp'.

MyApp.controller('CalculatorController', function ($scope) {
    $scope.add = function () {
        $scope.sum = $scope.num1 + $scope.num2;
    }
});

Assim que salvarmos o arquivo CalculatorApp.js após gravar o controlador, o teste passará conforme mostrado na imagem abaixo:

Assim que salvarmos o arquivo CalculatorApp.js após gravar o controlador, o teste passará

Etapa 16: Testando o AngularJS Factory com dados locais

Digamos que criamos um serviço AngularJS usando o nome do método de fábrica PlayerLocalApi. Este serviço está retornando dados locais que são codificados a partir de agora. O Serviço é criado conforme mostrado na lista abaixo:

MyApp.factory('PlayerLocalApi', function () {
    //var data = [{ "Name": "Dhananjay Kumar", "Age": 33.0 }];
    var data = [{ "Id": "1", "Name": "Dhananjay Kumar", "Age": 33.0 }, { "Id": "2", "Name": "Sachin Tendulkar", "Age": 22.0 }, { "Id": "6", "Name": "rahul dravid", "Age": 60.0 }];
    var PlayerLocalApi = {};
    PlayerLocalApi.getPlayers = function () {
        return data;
    }

    return PlayerLocalApi;
});

Podemos escrever um teste de unidade para testar o serviço, conforme mostrado na listagem abaixo:

describe('playerservicetest', function () {
        var data = [{ "Id": "1", "Name": "Dhananjay Kumar", "Age": 33.0 }, { "Id": "2", "Name": "Sachin Tendulkar", "Age": 22.0 }, { "Id": "6", "Name": "rahul dravid", "Age": 60.0 }];
        var PlayerLocalApi = {};

        beforeEach(inject(function (_PlayerLocalApi_) {
            PlayerLocalApi = _PlayerLocalApi_;
        }));
        it('should return search player data', function () {
            expect(PlayerLocalApi.getPlayers()).toEqual(data);

        });
    });

No trecho de código acima, estamos injetando o serviço PlayerLocalApi e, em seguida, chamando getPlayers nele. Além disso, temos dados de teste exatos para testar os retornos de dados do serviço. Este teste será aprovado.

Apenas para ter certeza de que escrevemos o teste corretamente, volte ao serviço e comente os segundos dados e remova o comentário dos primeiros dados para que o serviço modificado seja conforme listado abaixo:

MyApp.factory('PlayerLocalApi', function () {
    var data = [{ "Name": "Dhananjay Kumar", "Age": 33.0 }];
   //var data = [{ "Id": "1", "Name": "Dhananjay Kumar", "Age": 33.0 }, { "Id": "2", "Name": "Sachin Tendulkar", "Age": 22.0 }, { "Id": "6", "Name": "rahul dravid", "Age": 60.0 }];
    var PlayerLocalApi = {};
    PlayerLocalApi.getPlayers = function () {
        return data;
    }

    return PlayerLocalApi;
});

Agora, o serviço está retornando dados que não são os mesmos que os dados de teste no teste, portanto, obteremos um teste com falha, conforme mostrado na imagem abaixo:

Agora, o serviço está retornando dados que não são os mesmos que os dados de teste no teste, portanto, obteremos um teste com falha

E é assim que escrever testes de unidade para serviços que retornam dados locais.

Conclusão

Neste post abordamos muita coisa! Aprendemos a:

  • Set up a development environment
  • Configurar um ambiente de teste para jasmim
  • Setup a karma test runner environment
  • Escreva testes de unidade para filtro, controlador e serviço

Em outras postagens, veremos como escrever testes unitários para $http, serviços $q etc. Espero que você ache este post útil. Obrigado por ler!

Solicite uma demonstração