Lapidando ruby
-
Upload
mauricioszabo -
Category
News & Politics
-
view
1.311 -
download
0
Transcript of Lapidando ruby
Lapidando Ruby
A Work in Progress
Maurcio Eduardo [email protected]@mauricio_szabohttp://mauricioszabo.wordpress.com
Nesta Apresentao...
subject { You.new }Ruby.new.should be_false
knowledges.should include(RSpec)
should be_open_to_new_ideas
Por qu?
Aquela jovem uma das menos ignorantemente aparvalhadas formas de vida orgnica que eu j tive a profunda falta de prazer de no ser capaz de evitar encontrar
No Teremos...
Boas prticas
Prefira instncia
Entenda Ruby
Seja claroLogo - TO
Seja preciso
TESTES!
Ruby no ...
Perla.size == 0 or abort
PHPfor element in array
Javaarray.size.times { |i| element = array[i] }
Basic, Cobol, Pascal, C...a = create_person(:name => 'Foo')save_person(a)
Rescue Me!
(Estes cdigos so equivalentes!)
No Abuse da Linguagem
Ruby ajuda muito, mas use com moderaoyield sobre yield sobre yield sobre...Difcil de entender, e LENTO
No use coisas que podem depender da implementao de RubySe for necessrio fazer isso, ISOLE-AS e TESTE-AS INTENSIVAMENTE!
Evite depender de comportamentos no-documentadosreturn array.delete_if { |e| ... }
Evite Efeitos Colaterais
Se voc puder chamar um mtodo duas vezes e ele retornar o MESMO valor, melhor!
DEFina Direito!
Cdigo deve ser escrito como um jornal
No Seja Menos Claro
Flags?
Idente Tudo...
...MAS...
...Evite Identar
Floats?
Imprecisos
SPECs vo falharuse should be_close
Melhor ainda, use BigDecimal
No Modifique os Parmetros
OCP e MonkeyPatch
Classes devem ser ABERTAS para adio e FECHADAS para modificaoModificar mtodos legal, mas a maior fonte de problemas
TDD e BDD
Diferenas?
Como testar, e o qu testar?
Como manter a clareza?
Como evitar testes frgeis?
Como facilitar os testes?
BDD
No so testes, so comportamentosO teste um efeito colateral
Sapir-Whorf, ou Linguistic RelativityMesmo conceito usado pelo RSpec
Mesmo conceito por trs do Ruby
O que , afinal, um unit test?Ou um unit?
RSpec
person.old?.should == trueperson.old?.should be_true
person.should be_old
person.childs.size.should == 10person.should have(10).childs
array.size.should == 5array.should have(5).itens
RSpec on Rails
WTF???
Seja explcito...
Mas seja implcito!
Lembre-se SEMPRE do que voc est descrevendo!
Mocks
Muito usados nos Controllers do RailsQuando eu te perguntar, da prxima vez, exatamente quem voc, me responda um teste, ok?
Voc est testando, ou est escrevendo o cdigo final?
Mocks
Um aluno precisa escolher disciplinaseu SEI que um aluno estar logado...
eu SEI que o aluno estar cadastrado...
eu SEI que haver uma ou mais disciplinas...
mas NO SEI qual o cdigo.
Custom Matchers
Custom Matchers
Facilite seus testes!
O que os dois a seguir tem em comum?stub_model
Factories
Crie suas facilidades!stub_rest, talvez?
http://github.com/defunkt/fakefs
Ler - Scripted GUI Testing with Ruby
Mais uma coisa
Reek (gem install reek)Procura por smells em seu cdigo
Bom quando se est iniciando
Flog (gem install flog)Procura por cdigo torturado
Bom de ser usado em qualquer situao
Metrics_fuPlugin para Rails, incorpora Flog, Reek, RCov, etc...
Consideraes
Ler:Clean Code, Robert Martin
Design Patterns, GoF
Quando estiver programado:Melhorar sempre o cdigo
Cuidado com o termo melhorar
Evite:Comentrios explicando o que o cdigo faz
Dvidas?
The Power and Philosofy of Ruby: http://bit.ly/aMFAmj (Matz)
A new look at Test-Driven Development: http://bit.ly/7nYyhD (Dave Astels)
Clean Code: http://bit.ly/bUzV7k (Robert Martin)
Design Patterns in Ruby: http://bit.ly/9bKRQV (Russell Olsen)
Scripted GUI Testing with Ruby: http://bit.ly/a0etMC (Ian Dees)
def dupla_negativa pessoa_nao_tem_nome = @pessoa.nil? || @pessoa.nome == '' raise ArgumentError, 'Pessoa no possui nome' if pessoa_nao_tem_nome ...enddef atualizar_filhos return nil if @pessoa.nil? @pessoa.filhos.each { |filho| salvar_filho(filho) }end
def salvar_filho(filho) filho.pai = @pessoa filho.save!endprivate :salvar_filhodef atualizar_filhos if @pessoa.nil? || @pessoa.feminino? return nil else @pessoa.filhos.each do |filho| filho.pai = @pessoa filho.save! end endenddef salvar(params = {}) deve_deletar = params.delete :deletar deletar_parametros(params) if deve_deletarenddef salvar(params = {}) params = params.dup deve_deletar = params.delete :deletar deletar_parametros(params) if deve_deletarend
class ActiveRecord::Base def self.name return 'NAME' endend@pessoa = [email protected](false) #False??? Salva mas no salva?@pessoa = [email protected] :without_validations@pessoa = [email protected]_without_validationsputs 10/101.0 #0.0990099009900990.099009900990099 == 10/101.0 #falseit 'deve conseguir escolher a disciplina' do session['aluno'] = 'teste' aluno = Factory :aluno, :login => 'teste' disciplina = Factory :disciplina post :escolher, :disciplinas => [disciplina.id] aluno.should have(1).disciplinaenddescribe Aluno do before do @aluno = Factory.stub :aluno end
context 'com dados vlidos' do before do @aluno.stub!(:save).and_return(true) end
it 'deve...'describe Aluno do context 'com dados vlidos' do it 'deve...' do stub_aluno end end
def stub_aluno @aluno = Factory.stub :aluno @aluno.stub!(:save).and_return(true) endend
describe Sensor do it 'deve piscar se estiver muito quente' do @forno.muito_quente! @sensor.should be_blinking endendSpec::Matchers.create :be_a_valid do |who| match do |person| person.send(who).valid? end
failure_message_for_should do |person| "Expected person #{person.name} to be a valid #{who}" end
failure_message_for_should_not do |person| "Expected person #{person.name} to not be a valid #{who}" endenddescribe Person do it 'should create a valid student' do @person = Person.new(:student_data => { :grade => 1 }) @person.should be_a_valid(:student) end
it 'should create a invalid employee' do @person = Person.new @person.should_not be_a_valid(:employee) endenddef dividir(a, b) begin resultado = a / b rescue return nil end return resultadoenddef dividir(a, b) return a / b rescue nilenddef dividir(a, b) return a / brescue return nilendit "renders a list of people" do render response.should have_tag("tr>td", "name".to_s, 2)endit "assigns all people as @people" do Person.stub(:find).with(:all).and_return([mock_person]) get :index assigns[:people].should == [mock_person]enddef imprimir formatacao = formatar(:padrao) preparar_pagina(formatacao)end
def formatar_pagina(tipo) ...endprivate :formatar_pagina
def preparar_pagina(formatacao) ...enddef dupla_negativa unless [email protected]? && @pessoa.nome == '' ... else raise ArgumentError, 'err... bem... bom...' endenddef somar_numeros(a, b) @c += 1 return a + b + @cenddef somar_numeros c = @c + 1 return a + b + cend