Desenvolvimento

15 mai, 2018

Integrando seu frontend Angular no Visual Studio Team Services

Publicidade

Fala, galera!

Neste artigo, vou falar como podemos integrar nosso frontend dentro do Visual Studio Team Services (VSTS) – não só integrar, mas como podemos ter um processo de Continuos Integration com execução de testes de unidade usando Jasmine, minificação de arquivos Javascript com Gulp.

O que é Visual Studio Team Services

É uma solução baseada na nuvem para desenvolvedores que serve para controlar o Life Cycle de uma aplicação (ALM) que vai desde repositórios de códigos hospedado a acompanhamento de problemas de carga e compilações automatizadas (Builds). Como VSTS é uma solução na nuvem, pode ser acessado em qualquer lugar. Para usar, basta criar uma conta gratuitamente e nesta conta você pode incluir até cinco usuários. Crie sua conta grátis clicando aqui

Neste exemplo, vamos integrar nossa aplicação frontend ao Visual Studio Team Services. Nesta integração, vamos configurar o Continuos Integration da nossa aplicação, executar testes de unidade usando Jasmine e Karma JS, executar tarefas automatizadas no Gulp para minificação dos arquivos Javascript.

Neste exemplo, estou usando uma aplicação AngularJs na sua versão 1.6.x. Esta aplicação consume a API do Github e seu código fonte pode se encontrado no meu Github atráves deste link. Para testar a aplicação, basta abrir um terminal de comando e digitar o seguinte comando:

  • npm install
  • npm run start-server

Configurando o Gulp para execução de tarefas

Vamos configurar o Gulp para automatizar o processo de minificação dos arquivos Javascript. Abra o arquivo package.json e coloque a importação do Gulp como dependência do nosso projeto. Além do Gulp, vamos também colocar os pacotes necessários para a minificação dos arquivos Javascript, conforme exemplo abaixo:

"dependencies": {
    "jquery": "3.2.1",
    "bootstrap": "^3.3.7",
    "angular": "^1.6.6",
    "angular-resource": "^1.6.6",
    "angular-ui-router": "^1.0.3",
    "angular-mocks": "^1.6.10",
    "lite-server": "^2.3.0",
    "gulp": "3.9.1",
    "gulp-util": "3.0.8",
    "gulp-uglify": "3.0.0",
    "gulp-concat": "2.6.1",
    "gulp-rename": "1.2.2",
    "gulp-sourcemaps": "2.6.4",
    "gulp-plumber": "1.2.0",
    "run-sequence": "2.2.1"
}

Após fazer a alteração, abra o terminal e execute o comando npm install. Assim, vamos instalar localmente o Gulp e suas dependências para conseguirmos executar a tarefa de minificação. Feito isso, vamos criar um arquivo novo chamado gulpfile.js e colocar a tarefa de minificação dos nosso arquivos Javascript, conforme exemplo de código abaixo:

var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sourcemaps = require('gulp-sourcemaps');
var plumber = require('gulp-plumber');
var runSequence = require('run-sequence');
gulp.task('minificar-scripts', function () {
    return gulp.src([
                      'app/**/*-module.js',
                      '!app/tests/**/*.js',
                      'app/**/*.js',
                    ])
               .pipe(plumber())      
               .pipe(sourcemaps.init())      
               .pipe(concat('app-github.js'))
               .pipe(gulp.dest('dist/app'))
               .pipe(uglify())
               .pipe(rename({ extname: ".min.js"}))
               .pipe(sourcemaps.write('.'))
               .pipe(gulp.dest('dist/app'));
});
gulp.task('watch', function(){
   var watcher = gulp.watch('app/**/*.js',['minificar-scripts']);
   watcher.on( 'change', function( event ) {
        console.log( 'File ' + event.path + ' was ' + event.type );
    });
});
gulp.task('default', ['minificar-scripts']);

Configurando o Jasmine e Karma Runner para execução de Testes de Unidade

Neste ponto, estamos com o automatizador de tarefas Gulp configurado. Temos que configurar o Jasmine e o Karma Runner para executar teste de unidade no nosso projeto. O Jasmine é um Framework de teste de unidade para javascript e o Karma Runner é a biblioteca de execução de teste de unidade.

Primeiro, devemos abrir o package.json e adicionar as dependências para rodar o jasmine e o karma. Adicione as dependências, conforme código abaixo:

"dependencies": {
    "jquery": "3.2.1",
    "bootstrap": "^3.3.7",
    "angular": "^1.6.6",
    "angular-resource": "^1.6.6",
    "angular-ui-router": "^1.0.3",
    "angular-mocks": "^1.6.10",
    "lite-server": "^2.3.0",
    "gulp": "3.9.1",
    "gulp-util": "3.0.8",
    "gulp-uglify": "3.0.0",
    "gulp-concat": "2.6.1",
    "gulp-rename": "1.2.2",
    "gulp-sourcemaps": "2.6.4",
    "gulp-plumber": "1.2.0",
    "run-sequence": "2.2.1",
    "jasmine-core": "2.6.4",
    "karma": "1.7.1",
    "karma-jasmine": "1.1.0",
    "karma-chrome-launcher": "2.2.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "karma-junit-reporter": "1.2.0",
    "karma-phantomjs-launcher": "1.0.4",
    "phantom": "4.0.5"
}

Vamos configurar o Karma Runner para isso crie um novo arquivo chamado karma.config.js e adicione o código abaixo:

module.exports = function (config) {
  config.set({
        basePath: '',
        frameworks: ['jasmine'],
         files: [
           'node_modules/jquery/dist/jquery.min.js',
           'node_modules/angular/angular.min.js',
           'node_modules/angular-mocks/angular-mocks.js',
           'node_modules/angular-resource/angular-resource.min.js',
           'app/app-module.js',
           'app/factory/github-resource.js',
           'app/user-controller.js',
           'app/user-repository-controller.js',
           'app/tests/**/*.js'
        ],
        exclude: [
        ],
        preprocessors: {
        },
        reporters: ['progress', 'dots', 'kjhtml', 'junit'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_DISABLE,
        autoWatch: true,
        browsers: ['Chrome', 'PhantomJS'],
        singleRun: false,
        concurrency: 0,
        plugins: [
            'karma-jasmine',
            'karma-chrome-launcher',
            'karma-jasmine-html-reporter',
            'karma-phantomjs-launcher',
            'karma-junit-reporter',
        ],
        client: {
            captureConsole: false
        },
        junitReporter: {
            outputDir: 'testresults',
            outputFile: 'testResult.xml'
        }
    });
};

Com o nosso arquivo karma.config.js configurado, abra o packages.config e adicione o comando no qual iremos fazer o Karma Runner ser executado.

Adicione o comando conforme código abaixo:

"scripts": {
  "karma-test": "karma start karma.config.js --browsers Chrome --reporters kjhtml,dots",
"tfs-karma-test": "karma start karma.config.js --browsers PhantomJS --auto-watch=false  --single-run=true --reporters=progress,dots,junit"
},

Para testar o Karma Runner, abra um terminal e digite:

  • npm install
  • npm run karma-test

Configurando o Jasmine, o framework de Testes de Unidade

Agora vamos configurar o Jasmine; para isso, vamos criar testes de unidade para os nossos arquivos javascript. Neste exemplo, iremos testar o Controller de busca de usuário de Github.

Nós configuramos o Karma para executar todos os testes contido na pasta app/tests, assim, basta criarmos nossos testes de unidade dentro desta pasta. Para isso, vamos criar um arquivo chamado user-controller-specs.js e adicionar o código abaixo:

describe('Teste de Unidade de Busca de Usuário', function () {
    var $controller;
    var $scope;
    var resource;
    var $rootScope;
    var $q;
    function construirController() {
        var controller = $controller('userController', {
            $scope: $scope,
            githubResource: resource,
        });
        return controller;
    }
    beforeEach(function () {
        angular.mock.module('githubapp');
        angular.mock.inject(function (_$controller_, _$rootScope_, _githubResource_, _$q_) {
            resource = _githubResource_;
            $controller = _$controller_;
            $rootScope = _$rootScope_;
            $scope = _$rootScope_.$new();
            $q = _$q_;
        });
    });
    it('Deverá incicializar corretamente a controller', function () {
        $controller = construirController();
        expect($controller).not.toBe(null);
    });
    it ('Devera buscar usuário do github', function(){
        $controller = construirController();
        $scope.vm = {
            username: "rafaelcruz_net"
        };
        spyOn(resource.User, 'search').and.callFake(function(args){
            var response = {};
            response.items = [
                {
                    login: "rafaelcruz_net"
                }
            ];
            var deferred = $q.defer();
            deferred.resolve(response);
            return { $promise: deferred.promise };
   
        });
        $scope.buscarUsuario();
        expect($scope.vm).toBeDefined();
    });
});

Para testar, execute em um terminal o seguinte comando:

  • npm run karma-test

Se tudo ocorrer bem, devemos ver uma tela conforme abaixo:

Configurando o Visual Studio Team Services

Após todas as configurações locais funcionando, vamos configurar nosso Build (CI) para executar as tarefas. Para isso, clique no menu Build and Release e clique no botão no Botão New Definition, conforme imagem abaixo:

Vamos, agora, criar nossas tarefas para fazer o nosso CI do frontend:

Neste caso, estou usando o próprio Git do Visual Studio Team Services mas como podemos ver, temos diversas opções de integração desde do GitHub até uma fonte externa do Git.

Na próxima tela, escolha a opção Empty Process. Vamos adicionar a primeira tarefa, que seria a instalação dos pacotes do NPM, conforme imagem abaixo:

A terceira tarefa é a minificação dos nosso arquivos, vamos adicionar uma tarefa de Gulp conforme imagem abaixo:

Por último, vamos publicar o resultado dos nossos testes conforme imagem abaixo:

Clique em Save & Queue; com isso, nosso build irá disparar uma execução. Ao final da execução, devemos ter o resultado dos testes conforme imagem abaixo:

Quando executamos um teste que falha, o nosso Build sinaliza o teste que falhou conforme imagem abaixo:

Como podemos ver, nosso frontend Angular está todo integrado ao Visual Studio Team Services. Agora, a cada push que fizermos no Git, ele vai disparar um novo Build e executar essas tarefas.

Abraços e até a próxima.