Dev (Back & Front)

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.