Upload
jony-dos-santos-kostetzer
View
1.997
Download
0
Embed Size (px)
DESCRIPTION
Palestra sobre BDD ministrada no RS Rails 2009.* Os slides de "Live coding" foram alterados contendo o link para o repositório no GitHub.
Citation preview
Behaviour-Driven Developement com RubyTécnicas, ferramentas e experiências.
Jony dos Santos Kostetzer
Agenda
Definições
Por que escrever testes?
TDD e BDD
BDD
RSpec - explicações e live coding
Cucumber - explicações e live coding
Desenvolvimento orientado por testes
Em linhas gerais: Testar antes. Codificar depois.
“Como eu gostaria que minha aplicação se comportasse?”
Origem: eXtremme Programming
O Ciclo TDDred-green-refactor
Refactor Green
Red
Vantagens
1. Testando primeiro, você sabe exatamente o que seu sofware precisa fazer.
2. Foco: Escrever o código mais simples que resolve o problema.
3. Saber quando parar: Teste define quando se atinge o “suficiente”.
4. Código mais limpo e organizado.
Vantagens
5. Identificar o mais cedo possível problemas de regressão.
6. Segurança e refactoring sem medo.
7. Satisfação!
MANUTENABILIDADE!
Manutenabilidade?
Quão fácil é modificar o software.
Testes são fundamentais neste quesito - considerar o futuro.
Codigo sem testes = código legado.
Funciona? Sorte!
Além de tudo: seu código, sua carreira!
Bons programadores conseguem resolver um problema proposto de alguma forma.
Programadores excepcionais os resolvem de forma sustentável.
BDD - Behaviour-Driven Development
TDD + Novo Vocabulário + Novo ponto de vista
Ferramenta de design.
Nova abordagem: Foco em especificações de comportamento e não nos testes de verificação.
Testes são o meio. Ou seja, especificar comportamento utilizando testes.
Escrever software que importa!
Documentação executável
Clareza do código - comportamento
Testes em Ruby
Diversos frameworks.
Melhor x pior: Apenas escolha o que melhor lhe convir!
test/unit
miniunit
Shoulda
Micronaut
test-spec
RSpec
Cucumber
RSpec
DSL (Domain-Specific Language) para descrever comportamento de objetos.
Expressividade
Legibilidade
Similar a estar falando com um cliente.
BDD - Novo vocabulário
test/unit rspec
Asserções Expectativasshould /
should_not
Método de teste
Exemplo de código
it()
Caso de teste
Grupo de exemplos
describe()
Terminologias
test/unit rspec
class SomeClassTest < Test::Unit::TestCase
describe SomeClass
def test_something it "should do something descriptive"
def setup before(:each)
def teardown after(:each)
assert_equal 4, array.length array.length.should == 4
Grupo de exemplos (Example group)
describe Client do ... end
describe “A bank transaction” do ... end
describe Document, “being shared” do ... end
Exemplos de código (code examples)
it “should require a valid username” do ... end
it “should not charge a user when he has sufficient credits for the payment” do ... end
it “should not retrieve expired documents” do ... end
Expectativas (Expectations)
“ “.should be_blank
user.birthday.should == Date.today
client.active?.should be_false
client.should_not be_active
message.should match(/on Sunday/)
team.should have(11).players
Integrandoexample groups + code examples
Integrandoexample groups + code examples
Integrandoexample groups + code examples + contexts
Code examples
Matchers pré-existentes
Igualdade
===, ==, eql, equal
Texto
should match(/regex/), =~
Array
should include, length.should, have(3).items
Matchers
o.should be_closed -> o.closed?.should be_true
o.should be_an_instance_of(String) -> o.instance_of?(String).should be_true
o.should have_key(:id) -> o.has_key?(:id).should be_true
o.should have(5).characters -> o.characteres.length.should == 5
o.should have_at_least(12).rooms -> o.rooms.length.should >= 12
o.should be <= 7
Before/After
Antes de cada exemplo:
before(:each)
after(:each)
Antes de cada grupo de exemplos:
before(:all)
after(:all)
Outros idiomas
lambda { #codigo }.should change(algo) - (by, from, to)
lambda { #codigo }.should raise_error
lambda { #codigo }.should throw_symbol
Live codingRSpec
http://github.com/jonysk/rsrails_rspec
Cucumber
Ferramenta para descrever comportamento a partir da camada superior
No Rails: das views para os models. Substituem os Testes de Integração
Foco na interface e depois camadas inferiores (Outside-in)
O que o usuário espera? - Colaboração entre stakeholders e desenvolvedores para especificar.
Testes de aceitação
E por que não começar nos models? (Inside-out)
Construir o que você precisa ao invés do que você acha que precisa.
Descoberta gradual do que precisa ser implementado em baixo nível.
Relação Cucumber e RSpec
Cucumber: descrever o comportamento da aplicação.
“Make sure you’re writing the right code”
RSpec: descrever o comportamento dos objetos
“Make sure you’re writing the code right”
Red-green-refactor permanece:
Inicia no ciclo externo (Cucumber)
Termina no ciclo interno (RSpec)
Instalação
RSpec
gem install rspec rspec-rails
Para utilizar com Rails:
Dentro do projeto: script/generate rspec
Cucumber + webrat
gem install cucumber webrat
Para utilizar com Rails:
Dentro do projeto: script/generate cucumber
Cucumber features
Título / Narrativa / Cenários
Exemplo de feature
Internacionalização!
Implementando dos passos
Cucumber + webrat
Simulação de um browser
Comandos de integração intuitivos:
fill_in “campo”, :with => “valor”
visit “/pagina”
check “campo”
click_button “campo”
Matchers principais
should contain(‘text’)
should have_selector(‘#menu ul li.selected”, :content => “Dashboard”)
CSS3
should have_xpath(‘//node[@prop=”value”]’)
Implementando dos passos
Live codingCucumber
http://github.com/jonysk/rsrails_cucumber
Webrat + Selenium
gem install selenium-client
Habilitando Selenium no env.rb:
Desabilitar fixtures transacionais:
# Cucumber::Rails.use_transactional_fixtures
Webrat.configure do |config| config.mode = :selenium
end
Outros tópicos
Integração continua (Integrity, CruiseControl.rb)
Ferramentas: autotest, rcov, heckle, etc
Macros: muito atenção.
Obrigado!
twitter: @jonysk jonysk.net