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.