Setup do Sunspot-rails no Rspec

{ June 23rd, 2010 }


cmilfont

Autor: cmilfont

Tínhamos um problema nos testes unitários por débito técnico [na verdade desleixo mesmo] com o setup do Rspec e Sunspot-rails em determinado projeto. O problema era que mesmo para executar um simples teste unitário, levantávamos o Sunspot no spec_helper.rb.

Resolvi refatorar isso, acabei descobrindo no before/after do Spec::Runner.configure algo que eu não usava e que já existia desde o rspec “1.1.12 / 2009-01-11″, pelo que percebi no changelog.

O que fiz e parece bobo é separar pelo tipo (type) integration a subida de uma instancia real do Sunspot e agora dá para usar a estrutura de Rspec que o Sunspot disponibiliza para meus testes unitários.

#arquivo spec_helper.rb

ENV["RAILS_ENV"] ||= 'test'

require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment'))

require 'spec/autorun'
require 'spec/rails'
require 'rake'
require 'ruby-debug' unless RUBY_VERSION > '1.9'
require 'sunspot/rails/tasks'
require 'authlogic/test_case'
require 'sunspot/rails/spec_helper'

require 'database_cleaner'

#observe aqui que eu criei uma pasta support porque guardo algumas confs em arquivos contidos nela
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

Spec::Runner.configure do |config|
  config.use_transactional_fixtures = true
  config.use_instantiated_fixtures = false
  config.fixture_path = RAILS_ROOT + '/spec/fixtures/'

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  [:model, :helper, :controller].each {|type|
    config.before(:each, :type => type) do
      ::Sunspot.session = ::Sunspot::Rails::StubSessionProxy.new(::Sunspot.session)
    end
    config.after(:each, :type => type) do
      ::Sunspot.session = ::Sunspot.session.original_session
    end
  }

  config.before(:all, :type => :integration) do
    JojobaSunspot.new.start
  end
  config.after(:suite) do
    JojobaSunspot.new.stop
  end

end

Inspirado nesse post, eu adaptei para o código que uso ao subir o sunspot com linha de comando para os testes de integração. Observe no código anterior que importo configurações da pasta support, inclusive a classe JojobaSunspot, usada no after e before de integration.

require "net/http"

class JojobaSunspot

  def start
    @started = Time.now
    up_sunspot if starting
    up
  end

  def stop
    system("sunspot-solr stop --pid-dir=/tmp/pids") unless starting
  end

  private
  def port
    Sunspot::Rails::Server.new.port
  end

  def up_sunspot
    system("sunspot-solr start -p 8981 -d /tmp/solr_data_test --pid-dir=/tmp/pids --log-file=/tmp/solr_log_test.log --log-level=INFO")
  end

  def up
    while starting
      puts "Sunspot server is starting..."
    end
    puts "Sunspot server took #{'%.2f' % (Time.now - @started)} sec. to get up and running. Let's Jojoba!"
  end

  def starting
    begin
      sleep(1)
      request = Net::HTTP.get_response(URI.parse("http://localhost:#{port}/solr/"))
      false
    rescue Errno::ECONNREFUSED
      true
    end
  end

end

Desde que colocamos testes de integração o tempo de execução da bateria subiu muito, provocamos um setup ineficiente e desnecessário para os testes unitários. Fica a dica para quem passar pelo mesmo problema.

Posted in Rails, Rspec, Ruby, Sunspot ~ 1 Comment

Um amigo fez a seguinte pergunta que é muito comum hoje em dia com adoção crescente sobre linguagens dinâmicas, principalmente Ruby:

(…)”A dúvida era essa: Linguagens dinâmicas dão maiores possibilidades de inclusão de erro no código com isso aumentando de forma significativa a refatoração.”(…)

Em conversa com um excelente desenvolvedor aqui no Ceará, Delberto Muniz, ele escreveu a seguinte resposta:

Estava relendo um livro sobre os primórdios da programação e houve um debate semelhante: Os programadores Assembly achavam que programar em Fortan dava maiores possibilidades de erros porquê o programador não tinha total controle sobre o código gerado.

Dez anos depois o pessoal do Fortran falou mal do Algol porquê Algol abstraía demais e o programador não tinha total controle sobre a linguagem.

Aí veio o pessoal do C/C++ dizendo que Java abstraía demais, deixando margens a bugs serem introduzidos nos programas pelo compilador e/ou pela vm ou porquê simplesmente ele não estava alocando/desalocando memória manualmente.

Só mudaram as linguagens – o debate é sempre o mesmo: Se eu aumentar a abstração, meus programadores vão fazer besteira?

Se você está com essa dúvida, sinto muito: Você está nivelando por baixo e/ou não conhece seus desenvolvedores.

Posted in Engenharia de Software, Linguagens, Rails, Ruby, mercado ~ 9 Comments

Slides do Maré de Agilidade Fortaleza – 2009

{ August 9th, 2009 }


cmilfont

Autor: cmilfont

Posted in Behaviour Driven Development, Design Patterns, Engenharia de Software, Melhores práticas, Metodologia, Métodos Ágeis, Rails, Ruby, Test Driven, XP, palestras, xpce ~ No Comments