Go to English Blog

Executando testes de integração com JavaScript no Rails

Leia em 2 minutos

Sou um grande fã do Capybara. Começo todos os meus projetos com testes de aceitação escritos nele, além de usá-lo nos meus cursos de Rails. Por padrão, ele não permite que você execute testes que precisam de JavaScript, mas você verá como fazer isso nesse artigo.

O Capybara possui alguns adapters que permitem executar JavaScript. Você pode usar o Selenium, com suporte a Webkit headless. Neste artigo irei usar o Phantom.js, pois é o mais simples, já que não possui dependências externas (além do próprio Phantom.js) como QT ou ter um servidor X rodando.

Instalando o Phantom.js

Se você está no Mac, provavelmente usa o Homebrew, então a tarefa é bem simples! Basta executar o comando brew install.

$ brew install phantomjs
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/phantomjs-1.9.7.mavericks.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring phantomjs-1.9.7.mavericks.bottle.1.tar.gz
    /usr/local/Cellar/phantomjs/1.9.7: 104 files, 34M

Você também pode baixar o binário e colocá-lo no seu $PATH. Para instruções sobre como instalar no Linux ou Windows, veja a documentação.

Configurando seu projeto

Altere seu arquivo Gemfile, adicionando o Poltergeist e o Capybara ao seu projeto.

group :test do
  gem 'capybara'
  gem 'poltergeist'
end

Como uso RSpec, mostrarei como configurá-lo. Crie o arquivo spec/support/capybara.rb e adicione o conteúdo abaixo.

require 'capybara/rails'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist

Agora você já pode criar o seu primeiro teste com JavaScript. Crie o arquivo spec/features/hello_js_spec.rb e adicione um teste como o abaixo:

require 'rails_helper'

feature 'Running JavaScript', js: true do
  scenario 'it works' do
    visit root_path
    expect(page).to have_content('Hello from JavaScript')
  end
end

Perceba como estamos indicando que nossa funcionalidade faz uso de JavaScript; isso permitirá que filtros sejam aplicados na hora da execução, já que eles podem ser um pouco mais lentos e você pode querer pulá-los de vez em quando.

Agora, adicione o JavaScript abaixo ao arquivo de sua página inicial, antes fechar a tag <body>.

<script>
  document.body.appendChild(document.createTextNode('Hello from JavaScript'));
</script>

Pronto! Se tudo deu certo, é possível executar os seus testes. Para executar todos, use o bom e velho rspec.

$ rspec -f documentation

Running JavaScript
  it works

Finished in 1.83 seconds (files took 1.42 seconds to load)
1 example, 0 failures

Para executar apenas os testes que usam JavaScript, use rspec -t js.

$ rspec -f documentation
Run options: include {:js=>true}

Running JavaScript
  it works

Finished in 1.83 seconds (files took 1.42 seconds to load)
1 example, 0 failures

Finalmente, para executar todos os testes, mas não os de JavaScript, use rspec -t ~js.

$ rspec -f documentation -t ~js
Run options: exclude {:js=>true}

All examples were filtered out

Finished in 0.00021 seconds (files took 1.43 seconds to load)
0 examples, 0 failures

Lembre-se que o navegador utilizado pelo Phantom.js não é dos mais modernos. Embora seja baseado em Webkit, a versão utilizada não possui coisas como Function.prototype.bind, por exemplo. Por isso, lembre-se de usar algum polyfill como es5-shim.

A gem poltergeist tem diversas funcionalidades interessantes, como ler e definir cookies com JavaScript, definir headers HTTP, redimensionar a janela, tirar screenshots e muito mais. Por isso, não deixe de ler a documentação.