logo

Capybara + MiniTest + SitePrism - Seus Scripts Sem Firulas

No último ano eu andei me maravilhando com as facilidades do python e a simplicidade de fazer coisas, como por exemplo escrever testes automatizados inteligentes e diretos

Hoje voltei a trabalhar em uma empresa que usa bastante ruby e me senti extremamente incomodado em voltar a escrever scripts da forma que escrevia antes.

Quando se fala em automação de testes de aceitação de interface (ufa!), você só irá encontrar 2 opções: Ou você usa cucumber ou você usa Rspec. Não existe outra "escolha". Com tanto post que você lê na internet, da impressão que não existe outra forma de fazer isso e no final o modo cabresto é aplicado sem você perceber.

Se eu não vou usar BDD, porque raios eu preciso usar cucumber como test runner? ou RSpec? Não faz sentido!

No meu contexto atual, BDD não se aplica e já que dev entende linguagem de programação melhor que texto pleno, então porque complicar?

Esse post vai ser menos migalhado ( explicação de métodos) pois acredito que vocês já estão meio grandinhos para receber quase tudo mastigado né :)


Lets jump to the code

#TODO: arquivo runner de teste e colocar tudo no github

Para esse stack, seu GemList vai ficar um pouco parecido com isso:

source 'https://rubygems.org'

gem 'selenium-webdriver'  
gem 'capybara'  
gem 'site_prism'  
gem 'require_all'  
bundle install  

Tenha um arquivo test_helper (ou qualquer outro nome que você quiser) para fazer o setup do seu stack.

test_helper.rb

require 'minitest/autorun'  
require "selenium-webdriver"  
require 'capybara'  
require 'site_prism'  
require 'require_all'  

Ué, não tem _gem do minitest e vc ta colocando ele como require?_ Sim! O minitest vem built in no ruby junto com testunit e o autorun é o cara que vai te ajudar na execução dos casos de teste.

A gem require_all vai ajudar a fazer a magica de mapear seus arquivos contendo as classes de page object

Site prism é aquele cara legal que você consegue mapear os elementos da tela e criar funções dentro da própria classe.. sinistro de legal :)

require_all File.dirname(__FILE__) + '/page_objects'  

Você que já usou capybara, conhece os metodos de configuração dele para definir timeout, qual driver default, qual driver de javascript usar, qual browser usar e se vc está executando direto dentro de um rake server ou apontando seu script para fora do ambiente rails

Capybara.default_driver = :selenium  
Capybara.default_wait_time = 20

Capybara.register_driver :selenium do |app|  
    http_client = Selenium::WebDriver::Remote::Http::Default.new
    http_client.timeout = 200
    Capybara::Selenium::Driver.new(app, :browser => :firefox, :http_client => http_client)
end

Capybara.run_server = false  
Capybara.app_host = 'http://agiletesters.com.br'  

Para "finalizar" seu arquivo de configuração, vamos colocar um método de setup (executa antes de cada execução)

class AcceptanceTestSetup < Minitest::Test  
  include Capybara::DSL
  extend Minitest::Spec::DSL
  def setup
    puts "uuhuuu"
  end
end  

Neste Caso estou usando declarando que vou usar DSL do minitest e do capybara ( caso contrário não conseguiria usar as facilidades desses amigões :) )

O arquivo inteiro:

:test_helper.rb

require 'minitest/autorun'  
require "selenium-webdriver"  
require 'capybara'  
require 'site_prism'  
require 'require_all'


require_all File.dirname(__FILE__) + '/page_objects'

Capybara.javascript_driver = :webkit  
Capybara.default_driver = :selenium  
Capybara.default_wait_time = 20

Capybara.register_driver :selenium do |app|  
    http_client = Selenium::WebDriver::Remote::Http::Default.new
    http_client.timeout = 200
    Capybara::Selenium::Driver.new(app, :browser => :firefox, :http_client => http_client)
end

Capybara.run_server = false  
Capybara.app_host = 'http://agiletesters.com.br'

class AcceptanceTestSetup < Minitest::Test  
  include Capybara::DSL
  extend Minitest::Spec::DSL
  def setup
    puts "uuhuuu"
  end
end  

test_poc.rb

Esse vai ser nosso arquivo teste de teste :) (!!!)

Primeiro precisamos referenciar que vamos usar o test_helper:

require_relative "test_helper"  

Também precisamos especificar que nossa classe de teste vai herdar as coisas da classe AcceptanceTestSetup.

class HomeTest < AcceptanceTestSetup  

Apos declarar a classe, a gente pode começar a brincar com Site Prism. Para instanciar a classe DestaquePage (que já falo em seguida) para o objeto destaque, eu estou usando o helper do minitest (usado tb pelo siteprism) let(:objecto) {classe.new}

let(:destaque) { DestaquePage.new }  

Coloquei métodos de exemplo para mostrar que o minitest só pega métodos que comecem com a palavra mapeada test_

Como eu criei a instância destaque, nela existe um helper built para acessar quando é definido uma url.

  def metodo_que_nao_sera_executado
    sleep 2
  end

  def test_acesso_destaques
    visit('/')
    sleep 4
    destaque.load
    assert_equal(1,1)
  end

O arquivo intero

:test_poc.rb

require_relative "test_helper"

class HomeTest < AcceptanceTestSetup  
    let(:destaque) { DestaquePage.new }

  def metodo_que_nao_sera_executado
    sleep 2
  end

  def test_acesso_destaques
    visit('/')
    sleep 4
    destaque.load
    assert_equal(1,1)
  end
end  

page_objects/destaque_page.rb

Uma classe de exemplo para mostrar como mapear o Site Prism.

Ela herda site prism e você define os elementos da página especifica nele.
Maiores informações sobre métodos e afins, acesse a documentação do brinquedo.

class DestaquePage < SitePrism::Page  
  set_url "/destaques2015"
end  

External links:

https://github.com/jnicklas/capybara

https://github.com/seattlerb/minitest

http://ruby-journal.com/minitest-let-is-lazy/ http://chriskottom.com/blog/2014/10/4-fantastic-ways-to-set-up-state-in-minitest/

https://github.com/natritmeyer/site_prism

http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html

http://chrismdp.com/2013/01/bdd-is-not-cucumber/

Este post está vivo e vai ser atualizado na medida do possível :)
(obrigado aos revisores @sammy, @stefan, @ramses, @deivyson, @gabriel, @edu)

Dúvidas, sugestões e críticas são bem vindas!


Sobre o Autor: Leonardo Galani é Agile Tester, dev, gamer, dj and etc. Mantém o fórum http://agiletesters.com.br | http://leonardobg.com.br (profile)| http://lazytester.com (blog em inglês)
http://br.linkedin.com/in/leonardogalani/

comments powered by Disqus