Testando Javascript no Rails 4 com Karma + Jasmine + Code Coverage
Para projetos Rails temos como alternativa para testes de Javascript a gem jasmine da pivotal. Ela é muito simples de ser instalada e configurada, porém, exitem algumas coisas nela que me incomodam. Vamos lá:
1. Ela é uma gem. Eu tenho um pé atrás de usar coisas do Front no Gemfile. Acho que Gemfile é pra coisas do Ruby. Prefiro manter as ferramentas do front em Node.js e/ou Bower.
2. Ou roda tudo no Browser ou então roda tudo no console. Se você está acostumado a fazer TDD e gosta de ver os seus testes rodando automaticamente, isso é um saco. Ou você fica dando F5 freneticamente no browser ou então fica rodando $ rake jasmine:ci
sempre que quiser avaliar os testes.
3. Com o Jasmine 2 ficou ainda mais difícil. Você não consegue rodar um único teste isoladamente. Sem contar que ver os erros no browser é um saco.
4. Integração com plugins: você já tentou configurar algum plugin para coverage? Então… vou parar minha conversa por aqui.
O que você verá neste post
Este post mostrará, de uma forma bem direta, como instalar as seguintes ferramentas:
- Karma: abrirá o browser por debaixo dos panos e fará a ponte entre o browser e os testes. Ele ficará ouvindo as modificações nos arquivos *_spec.js e rodará os testes sempre que isso acontecer.
- Jasmine: será o cara que de fato rodará os testes.
- Karma Coverage (Istanbul): aferirá o nível de cobertura de testes do código.
- Karma Mocha Reporter: formatará os resultados dos testes parecido com o
--format documentation
do rspec.
Pré-requisitos
Eu presumirei que você terá instalado no seu computador:
- Ruby on Rails 4.0.x
- Node.js >= 0.10.26
Se você é novo em Ruby on Rails, talvez este meu outro post lhe ajude.
Se você é novo em Node.js, sugiro que consulte a página do projeto. O pessoal vive achando meios mais simples de instalá-lo a cada dia.
Um novo projeto
Pra efeitos práticos, eu criarei um projeto Ruby on Rails do zero. Infelizmente não abordarei o uso do Coffee Script, pois eu não uso e não tenho experiência com o mesmo. Abordarei apenas Javascript puro.
$ rails new rails-karma
$ cd rails-karma
$ mkdir spec/
$ mkdir spec/javascripts/
Para realizar nossos testes, vamos criar uma classe javascript chamada Example e cobrir 100% de testes. Aí estão os arquivos:
Arquivo contendo o código:
// arquivo: rails-karma/app/assets/javascripts/example.js
function Example() {
}
Example.prototype.foo = function() {
return "bar";
}
Example.prototype.bar = function() {
return "foo";
}
Arquivo contendo os testes:
// arquivo: rails-karma/spec/javascripts/example_spec.js
describe("Example", function(){
var example;
beforeEach(function() {
example = new Example();
})
it("returns 'bar'", function() {
expect(example.foo()).toEqual("bar");
})
// Este teste está propositalmente comentado
// para que o coverage não acuse 100% de cobertura.
//
// it("returns 'foo'", function() {
// expect(example.bar()).toEqual("foo");
// })
});
Instalando o que interessa
A primeira coisa que nós vamos fazer é criar o arquivo package.json
descrevendo as dependências do projeto:
// arquivo: rails-karma/package.json
{
"private": true,
"devDependencies": {
"karma": "0.12.22",
"karma-chrome-launcher": "0.1.4",
"karma-jasmine": "0.1.5",
"karma-coverage": "0.2.6",
"karma-mocha-reporter": "0.3.0"
}
}
Agora vamos rodar o npm para que ele instale cada dependência:
$ npm install
Essa é a hora de você pegar um café, pois vai demorar pra cacete!
As dependências serão instaladas na pasta rails-karma/node_modules
. Aproveite e coloque esta pasta no .gitignore
, pois não há necessidade de versionar.
Seja também um dev legal e coloque no Readme do projeto que cada desenvolvedor terá que rodar o npm install
.
Configurações
Você precisa criar o arquivo karma.conf
. Ele é que dirá como o karma deve se comportar. Eu não vou descrever o que cada linha faz, pois o arquivo é muito simples.
De qualquer forma, vale a pena dar uma olhadinha na documentação. Eu deixarei os links do que foi usado no final deste post.
// arquivo: rails-karma/spec/javascripts/karma.conf
module.exports = function(config) {
config.set({
basePath: "../..",
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
singleRun: false,
frameworks: ["jasmine"],
files: [
"app/assets/javascripts/**/*.js",
"spec/javascripts/**/*_spec.js"
],
exclude: [
],
preprocessors: {
"app/assets/javascripts/**/*.js": ["coverage"]
},
reporters: ["mocha", "coverage"],
browsers: ["Chrome"],
coverageReporter: {
type: "lcov",
dir: "coverage/"
},
mochaReporter: {
output: "autowatch"
}
});
};
Executar os testes
Podemos executar desta forma:
$ ./node_modules/karma/bin/karma start ./spec/javascripts/karma.conf
Você verá uma tela semelhante a que está abaixo:
Sempre que algum arquivo de testes for modificado, o karma automaticamente executará a suite de testes novamente.
Para interromper o monitoramento dos testes, basta usar CTRL+C
.
Podemos facilitar um pouco mais a execução dos testes. Para isso precisamos instalar globalmente mais um módulo no node.js:
$ sudo npm install -g karma-cli
A partir de agora os testes podem ser executados assim:
$ karma start ./spec/javascripts/karma.conf
Coverage
Lembra que um de nossos testes estava comentado?
// arquivo: rails-karma/spec/javascripts/example_spec.js
...
// it("returns 'foo'", function() {
// expect(example.bar()).toEqual("foo");
// })
Ele foi deixado assim para podermos ver o relatório de cobertura indicando que tínhamos código descoberto.
O relatório está disponível na pasta rails-karma/coverage/seu-browser/lcov-report/index.html
. Vá até lá e abra este html. Você verá algo parecido com as imagens abaixo:
Visão 1:
Visão 2:
Visão 3:
Note que o coverage indicou precisamente o código que não está coberto.
Se você descomentar o teste e der um F5 no browser, você verá que o relatório será instantaneamente atualizado e indicará 100% de cobertura.
Fechando
É isso ái. Temos o básico pra trabalhar. Aconselho que você leia a documentação de cada módulo que utilizamos. Eis aí os links:
http://karma-runner.github.io/0.12/index.html
http://karma-runner.github.io/0.12/config/configuration-file.html
https://github.com/karma-runner/karma-coverage
https://github.com/litixsoft/karma-mocha-reporter
https://github.com/karma-runner/karma-cli/releases
https://www.npmjs.org/doc/files/package.json.html
Não importa se você testa antes ou depois. O que importa é você entregar código testado.
Pra mim, entregar código sem teste é a mesma coisa que entregar serviço pela metade.
Um abraço.