Colorindo o output dos testes no Rails
13/06/07
Se você anda escrevendo muitos testes mas precisa se esforçar um pouco para ler a saída gerada por eles, experimente a gem RedGreen, criada por Pat Eyler. Ela não faz nada além de colorir com a cor verde os testes que passaram e com a cor vermelha os testes que falharam. Simples assim, mas muito útil!
Para instalá-lo, execute o comando sudo gem install redgreen e adicione o código require 'redgreen' no fim do arquivo "environment.rb".
- Permalink
- Trackback
- Comentários (7)
- Ao som de: NOFX – Drop The World
Como migrar suas Stored Procedures no ambiente de teste
11/06/07
Normalmente, evito utilizar Stored Procedures e Functions até onde posso, mas no Spesa, não foi possível, devido uma quantidade de consultas "avançadas" que são feitas. Se não as utilizasse, a repetição de código seria absurdamente grande e, por conseguinte, seria impossível de se fazer eventuais modificações. Como estou refatorando o código do Spesa e escrevendo testes para cada item do sistema, caí em um problema um pouco incômodo na hora da migração.
Não sei se você sabe, mas toda vez que você quer sincronizar o seu banco de testes com o de desenvolvimento, basta executar o comando rake db:test:prepare. O grande problema deste comando é que ele não leva em consideração os arquivos de migração, mas sim o arquivo schema.rb, que não adiciona queries executadas através do método execute. Para corrigir isto, basta executar o comando rake db:migrate RAILS_ENV="test".
Update: depois de fazer alguns testes, vi que as stored procedures continuavam a serem excluídas. O único jeito foi estender o ActiveRecord para ele fazer o dump das funções e salvá-las no arquivo schema.rb. Basta adicionar o código abaixo no arquivo environment.rb.
module ActiveRecord
class SchemaDumper
def dump(stream)
header(stream)
tables(stream)
functions(stream)
trailer(stream)
stream
end
private
def functions(stream)
result = @connection.execute <<QUERY
SELECT
ROUTINE_NAME AS name
FROM
INFORMATION_SCHEMA.ROUTINES
WHERE
ROUTINE_TYPE='FUNCTION' AND
ROUTINE_SCHEMA='#{@connection.current_database}'
QUERY
result.each do |row|
stream = function(row[0], stream)
end
end
def function(name, stream)
result = @connection.execute "SHOW CREATE FUNCTION #{name}"
fields = result.fetch_hash
func = fields['Create Function'].gsub(/CREATE DEFINER.*? FUNCTION/, "CREATE FUNCTION")
stream.puts <<FUNCTION
execute <<QUERY
#{func}
QUERY
FUNCTION
stream
end
end
end - Permalink
- Trackback
- Comentários (3)
- Ao som de: The Get Up Kids – Conversation
Use o método save! ao escrever seus testes
03/06/07
Toda vez que você estiver escrevendo um teste — seja ele qual for — e tiver que chamar o método save, opte pelo método save!. A diferença entre eles é que o primeiro retorna true ou false em caso de sucesso ou falha, respectivamente. Já o segundo, irá disparar a exceção ActiveRecord::RecordInvalid, caso o modelo seja inválido em relação às suas regras de validação.
Aplicado aos testes, a vantagem do método save! está na dependência de alguma alteração do modelo para testar uma outra situação. Imagine o seguinte modelo:
class User < ActiveRecord::Base
validates_length_of :password,
:minimum => 4,
:message => 'A senha deve ter no mínimo 4 caracteres'
attr_accessor :password
end
Já o teste irá validar se um usuário pode se logar com um cookie expirado.
def test_should_fail_expired_cookie_login
user = users(:quentin)
user.remember_me
user.remember_token_expires_at = 5.minutes.ago
user.save
@request.cookies["auth_token"] = cookie_for(:quentin)
get :index
assert !@controller.send(:logged_in?)
end
Ao executá-lo, ele falharia porque o atributo password não foi definido e o método validates_length_of invalidaria nosso modelo, só que você não iria ter nenhuma indicação de que esse foi o motivo. Neste caso, se você trocar a linha user.save por user.save!, uma exceção seria disparada, indicando qual validação não passou. No modelo você poderia utilizar o seguinte código para validar o modelo:
class User < ActiveRecord::Base
validates_length_of :password,
:minimum => 4,
:message => 'A senha deve ter no mínimo 4 caracteres',
:if => :require_password?
attr_accessor :password
private
def require_password?
!password.blank?
end
end 