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.