Neste artigo veremos como criar unit tests para trabalhar com javascript de maneira integrada ao Visual Studio e ao TFS Build, visando garantir maior estabilidade do código e qualidade contínua das nossas aplicações.

Introdução

Nas aplicações modernas tem se tornado muito comum a utilização de javascript para operações cada vez mais complexas que incluem muitas vezes regras de negócio, cálculos e etc. Com o surgimento dos diversos frameworks de mercado a utilização de javascript como parte da estratégia de desenvolvimento tem se tornado cada vez mais comum, seja em startups ou em grandes corporações.

Em contrapartida pouco se fala sobre qualidade contínua para os artefatos gerados nesse mundo, sejam arquivos JS contendo diversas rotinas, ou simplesmente métodos criados em uma determinada página, para sanar uma demanda pontual.

Uma forma de garantir a qualidade e também a estabilidade do código é a utilização de unit tests como parte integrada de uma estratégia de compilação ou mesmo sendo executada manualmente pela equipe de desenvolvedores.

Nesse artigo veremos como criar um unit test para javascript e como automatizá-los em um build, garantindo assim a qualidade contínua do nosso código. Lembrando que não iremos abordar os conceitos por trás do unit test apenas a implementação.

Qualidade e a plataforma Visual Studio ALM

A plataforma Visual Studio ALM tem uma capacidade de extensibilidade muito grande que inclui não só com produtos Microsoft mas também produtos e ferramentas externas, e essa extensibilidade fornece para o time de desenvolvimento alternativas poderosas na hora de otimizar recursos, atingir objetivos estratégicos e o principal evitar desperdícios no ciclo de desenvolvimento. No ponto de vista de qualidade a plataforma fornece recursos que vão desde testes manuais até automatizados e de carga, mas o que nos interessa hoje são os unit tests, que podemos utilizar para garantir que nosso código está estável e que novas implementações não impactaram nas funcionalidades antes desenvolvidas – vai muito além claro, mas para o nosso artigo esse é o ponto importante.

Porém esses unit tests apesar de atenderem grande parte dos cenários não conseguem nativamente atender a essas implementações feitas em javascript ou pelo menos não de maneira simples e produtiva. Para isso iremos utilizar da capacidade de extensibilidade da plataforma para utilizar dois componentes que farão essa tratativa e integraram os dados coletados tanto na nossa IDE quanto no nosso build, e também veremos o quão expansível é a plataforma.

Cenário

No cenário que utilizamos nesse artigo temos uma aplicação ASP.NET MVC que possui um arquivo JS com um método responsável por um cálculo de grande importância para a aplicação. Recentemente o time de homologação e alguns clientes tem relatado frequentes erros nesse cálculo, e juntamente com o time de arquitetura conseguimos identificar que o problema ocorre devido a frequentes manutenções e integrações com fontes do time de sustentação. Foi solicitado que criássemos um processo para garantir a qualidade do código, independente de qual time altere.

Para atingir esse objetivo iremos realizar a criação de testes unitários para esse método que apresenta constante falhas e incluiremos o mesmo no processo de build do time.

A única premissa imposta pelo time de gestão é que tudo isso seja feito com o menor impacto possível para os times e para a produtividade dos mesmos.

Importante ressaltar que para efeito de exemplo iremos utilizar uma rotina simples e bem pequena, mas o que veremos aqui se aplica a cenários de alta complexidade também.

Os responsáveis pela “mágica”

Conforme dito anteriormente para esse cenário iremos utilizar dois componentes open source e que são muito utilizados. Esses componentes são:

  1. QUnit: um framework para unit tests javascript.
  2. Chutzpah: um test runner open source para javascript e também uma extensão para o Team Explorer para que possamos acompanhar visualmente da mesma forma que acompanhamos os outros testes unitários. Possui também outras funcionalidades, que vão além do nosso cenário.

Preparando o ambiente

Para a reprodução do nosso cenário precisaremos ter criado um projeto do tipo ASP.NET MVC (que é a nossa aplicação em questão) e incluí-lo no version control do TFS. No exemplo utilizado foi criado um team project exclusivo para esse projeto com um diretório Main onde ficará o código fonte da aplicação.

Após isso iremos incluir na mesma solution um projeto do tipo Unit Test e remover a classe padrão criada e definindo-o como projeto padrão (lembrando que nosso objetivo pouco tem a ver com o projeto MVC estamos focando nos testes), deixando-o da forma que vemos na figura abaixo.

Imagem 1 – Estrutura da solução

Após isso iremos abrir o console do Nuget (menu Tools > NuGet Package Manager > Package Manager Console) e iremos realizar o download e instalação do QUnit. Para isso utilizaremos a linha de comando abaixo.

Install-Package QUnit-MVC

O próximo passo é adicionarmos a extensão Chutzpah à solução. Para isso basta irmos até o menu Tools > Extensions e Update e procurarmos pela extensão, conforme podemos ver na imagem abaixo. Ela é a responsável pela integração entre o que está ocorrendo no engine de testes e a IDE ou no caso automatizado para o TFS Build

Imagem 2 – Extensão Chutaspah

Passada a instalação será solicitado que reiniciemos o Visual Studio. Feito isso nosso ambiente está pronto para implementarmos os unit tests.

A criação do Unit Test

Agora iremos incluir no nosso projeto ASP.NET MVC o script JS que queremos validar. Dentro da pasta scripts iremos incluir um arquivo JS Metodos.js e o conteúdo desse arquivo está apresentado abaixo.

Imagem 3 – Método que será validado nos testes

Para que possamos entender: esse método é o método reportado pelo time de homologação, e onde ocorre a quebra constante. Na prática nos nossos projetos de produção essa etapa não seria necessária já que testaríamos algo implementado anteriormente.

Agora iremos incluir no nosso projeto de testes um arquivo JS chamado MetodoTest.js. Esse arquivo irá conter os testes do respectivo método. O conteúdo desse nosso teste será simplesmente um assert (ok) para validar se o retorno está de acordo com o que queremos. Na imagem abaixo temos o conteúdo do teste.

Imagem 4 – Criação do teste unitário para o método

Agora para efeito de alinhamento vejamos como ficará nossa estrutura da solução.

Imagem 5 – Estrutura do projeto

Feito isso temos nosso método implementado e nosso teste para esse método também implementado. E como podemos identificar se a execução está OK? Se está havendo algum problema ou algo do tipo? Se realmente nosso método está consistente e o unit test fazendo seu papel? Da mesma forma que fazemos com testes padrões do Visual Studio, basta irmos no menu Test > Run e selecionar uma das opções disponíveis. Outra opção é exibirmos a janela do Test Explorer e então conseguiremos identificar os testes criados e executar o que queremos. A figura abaixo mostra essa opção.

Imagem 6 – Janela do Test Explorer com o nosso teste, com o teste criado

Basta clicarmos com o botão direito do mouse no teste e selecionar a opção “Run Selected Test”. Se tudo ocorreu bem o resultado será semelhante ao da imagem abaixo.

Imagem 7 – Resultado da execução do teste unitário (sucesso)

Tudo bem, mas o que garante que o método realmente funcionou e está sendo validado o valor informado? Para isso podemos alterar o valor da variável expected para outro número qualquer, nesse caso nosso teste deverá falhar, conforme vamos na imagem abaixo.

Imagem 8 – Resultado da execução do teste unitário (falha)

Com isso temos nosso método sendo “observado” por um unit test, o que já permite aos desenvolvedores ou time de arquitetura por exemplo executar manualmente os unit tests e identificar possíveis quebras no código.

Caso não quiséssemos integrar nosso unit test ao build poderíamos para por aqui, porém queremos garantir essa mesma qualidade no processo de build para que não seja impactado a produtividade do time.

Integrando nosso Unit Test com o TFS Build

Agora iremos garantir que esse teste será executado no nosso build automático para que possamos garantir a qualidade continua do nosso código.

O primeiro passo que tomaremos é realizar o download do Chutzpah via VS Gallery (o link utilizado nesse artigo está nas referências). Faremos o download de um arquivo .vsix, porém iremos alterar a extensão para .zip e extrair o conteúdo do arquivo. Após a extração teremos algo semelhante ao da imagem abaixo (claro que dependendo da versão os arquivos podem mudar)

Imagem 9 – Conteúdo extraído

Mas por que precisamos fazer isso? Para o build do TFS quando estamos trabalhando com componentes externos que serão integrados no Build e que serão utilizados no processo de build precisamos esses componentes em algum local do nosso version control para que o engine do Build possa acessa-los de acordo com a demanda de execução. Para isso iremos criar uma pasta “Binaries” no version control do nosso team project e incluir o conteúdo desse diretório no mesmo – para efeito de Build não é necessário todo o conteúdo do diretório, mas por se tratar de poucos arquivos iremos colocar todos para conseguirmos ter um histórico dos nossos assemblies.

Imagem 10 – Estrutura do version control com os arquivos inclusos

Com os binários necessários versionados o próximo passo é configurar o Build Controller para suportar essas execuções. Para isso iremos acessar o console de gerenciamento do TFS, em “Build Configuration” iremos clicar em “Properties” do Build Controller, no campo “Version control path to custom builds” iremos selecionar no nosso version control o diretório “Binaries” onde incluímos o conteúdo extraído.

Imagem 11 – Configuração do build controller

Após esse procedimento realizado iremos criar uma definição de build com base no template “TfvcTemplate.12.xaml”. Nesse ponto criaremos uma definição da maneira que estamos acostumados, porém opção “Automated tests” iremos selecionar o Test Source disponível clicando no botão “...” localizado na direita.

Imagem 12 – Parametrização da build definition

No campo “Test assembly files especification” manteremos o que está e incluiremos a opção **\*.js .

Imagem 13 – Inclusão do tipo de arquivo no Test Source

Pronto. Nossa definição está pronta para suportar a execução dos unit tests que criamos, só falta um detalhe: todos os arquivos js que contém os testes precisam estar configurados para serem copiados para o diretório de output sempre. Para isso basta selecionarmos os arquivos clicar em properties e marcar a opção “Copy to Output directory” como “Copy Always”. Agora basta iniciarmos um build para vermos se as configurações estão corretas.

Imagem 14 – Resultado da execução do teste

Pronto. Nosso build está executando nosso unit test javascipt e coletando a quantidade e quais testes passaram ou não.

Com isso conseguimos controlar continuamente a qualidade e evitar possíveis quebras no código, garantindo a evolução do nosso código e garantindo sua qualidade.

Espero que seja útil pessoal. Até a próxima.

Referências

https://visualstudiogallery.msdn.microsoft.com/f8741f04-bae4-4900-81c7-7c9bfb9ed1fe

https://qunitjs.com/